环境变量 LOGNAME 或 USER 与有效用户 ID 不对应

环境变量 LOGNAME 或 USER 与有效用户 ID 不对应

我正在运行 Ubuntu 20.04.6 LTS 服务器。该服务器托管一些 Virtualbox 虚拟机,我每天都会使用 bash 脚本备份这些虚拟机。这很有效。当备份成功时,bash 脚本还会发送一些电子邮件,如果备份失败,我会通过电子邮件收到错误消息。

最近,我开始收到一些电子邮件,Cron Daemon内容如下:

WARNING: Environment variable LOGNAME or USER does not correspond to effective user id.

主题向我展示了显然导致该问题的脚本:Cron <user@server> /home/user/buprod.sh

该脚本是通过 crontab 以普通用户身份运行的,而不是 root 用户。更令人费解的是,我正在备份多个虚拟机,但只从一个脚本中收到该警告消息,而其他脚本中没有。

我是否需要担心警告信息?如何才能避免它?

编辑(根据评论提供更多信息):

crontab 位于以下位置var/spool/cron/crontabs/matth,其内容如下:

# For more information see the manual pages of crontab(5) and cron(8)
# m h  dom mon dow   command
SHELL=/bin/bash

04 2 * * 1 /home/matth/buproxy.sh
24 2 * * * /home/matth/buprod.sh

引发警告信息的脚本是buprod.sh,其内容如下:

#!/bin/bash

# =============== Set your variables here ===============
MYMAIL="[email protected]"
VMDIR="/home/matth/VirtualBox\ VMs/ERPNext\ Production/"
EXPORTDIR="/mnt/video/Backup/vmbackup/"
TEMPDIR="/home/matth/temp/"
VMTMPDIR="/home/matth/temp/ERPNext\ Production/"
LOGDIR="/home/matth/logs/"
LOGNAME="erpnextprod.log"
VM="ERPNext Production"
ERR="nothing"
SECONDS=0
STARTUP=1
COPY=1
# =======================================================
# No manual changes needed below this point
# =======================================================

LOGFILE="$LOGDIR$(date +"%Y-%m-%d-%T")-$LOGNAME"

cdt=$(date)
echo "${cdt}: Backing up VM ${VM}" >> $LOGFILE

# Get the vm state
VMSTATE=$(vboxmanage showvminfo "$VM" --machinereadable | grep "VMState=" | cut -f 2 -d "=")
cdt=$(date)
echo "${cdt}: ${VM}'s state is: ${VMSTATE}." &>> $LOGFILE

# If the VM's state is running or paused, save its state
if [[ $VMSTATE == \"poweroff\" ]]; then
  # skip the wait
  cdt=$(date)
  echo "${cdt}: VM ${VM} is already powered off" &>> $LOGFILE
  STARTUP=0
else
  # Shut down the VM
  cdt=$(date)
  echo "${cdt}: Shutting down the VM ${VM}" &>> $LOGFILE
  vboxmanage controlvm "$VM" acpipowerbutton
  if [ $? -ne 0 ]; then ERR="shutting down"; fi
  # cdt=$(date)
  # echo "${cdt}: Waiting 120 seconds to let the VM ${VM} shut down" &>> $LOGFILE
  # sleep 60s
fi

max_wait=$((SECONDS+120))
cnt=1
# Check state of VM
VMSTATE=$(vboxmanage showvminfo "$VM" --machinereadable | grep "VMState=" | cut -f 2 -d "=")
# Wait a maximum of 120 seconds to avoid an infinite loop in case the VM can't be stopped
while [[ $VMSTATE != \"poweroff\" ]]
do
   cdt=$(date)
   echo "${cdt}: ${cnt} loop(s) waiting for the VM ${VM} to shut down. Current state is ${VMSTATE}" &>> $LOGFILE
   # Wait a few seconds before checking again
   sleep 10s
   # Checking state of VM again
   VMSTATE=$(vboxmanage showvminfo "$VM" --machinereadable | grep "VMState=" | cut -f 2 -d "=")
   cnt=$(( $cnt + 1 ))
   # If loop has taken more than 60 seconds, break it to avoid an infinite loop
   if [ $SECONDS -gt $max_wait ]; then break; fi
done

# Check if VM is now powered off
VMSTATE=$(vboxmanage showvminfo "$VM" --machinereadable | grep "VMState=" | cut -f 2 -d "=")
cdt=$(date)
echo "${cdt}: ${VM}'s state is: ${VMSTATE}." &>> $LOGFILE

if [[ $VMSTATE == \"poweroff\" ]]; then
   # First copy it to a local directory to have a faster copy
   eval cp -R "${VMDIR}" $TEMPDIR
#   eval cp -R "${VMDIR}" $EXPORTDIR
   cdt=$(date)
   echo "${cdt}: VM ${VM} has been copied from ${VMDIR} to ${TEMPDIR}" &>> $LOGFILE
else
   ERR="not powered off"
   cdt=$(date)
   echo "${cdt}: Not exporting because the VM ${VM} is not powered off." &>> $LOGFILE
   COPY=0
fi

if [[ $STARTUP == 1 ]]; then
   vboxmanage startvm "$VM" --type headless &>> $LOGFILE
   if [ $? -ne 0 ]; then
      ERR="starting up"
   else
      cdt=$(date)
      echo "${cdt}: VM is started up again" &>> $LOGFILE
   fi
fi

# Calculate duration
duration=$SECONDS
duration="Operation took $(($duration / 60)) minutes, $(($duration % 60)) seconds." &>> $LOGFILE

if [[ $COPY==1 ]]; then
   # Now copy off-machine
   eval cp -R "${VMTMPDIR}" $EXPORTDIR
   cdt=$(date)
   echo "${cdt}: VM ${VM} has been copied from ${VMTMPDIR} to ${EXPORTDIR}" &>> $LOGFILE
   eval rm -R "${VMTMPDIR}"
   cdt=$(date)
   echo "${cdt}: Temporary directory ${VMTMPDIR} has been deleted" &>> $LOGFILE
   # Calculate duration
   duration=$SECONDS
   duration="Operation including copy to NAS took $(($duration / 60)) minutes, $(($duration % 60)) seconds." &>> $LOGFI>
fi

# Notify the admin
if [ "$ERR" == "nothing" ]; then
  MAILSUBJECT="VM ${VM} succesfully backed up"
  MAILBODY="Virtual Machine ${VM} was succesfully backed up!"
  MAILBODY="$MAILBODY"$'\n'"$duration"
#  MAILBODY=$(echo $MAILBODY && cat $LOGFILE)
else
  MAILSUBJECT="Error $ERR VM ${VM}"
  MAILBODY="There was an error ${ERR} VM ${VM}."
  MAILBODY=$(echo $MAILBODY && cat $LOGFILE)
fi

# Send the mail
echo "$MAILBODY" | mail -s "$MAILSUBJECT" $MYMAIL

编辑 2:提供以下附加详细信息

我检查了脚本生成的日志文件。根据日志文件,错误似乎是由虚拟机重启引起的。

At 27: USER=, LOGNAME=matth
Fri May  3 11:38:01 AM HKT 2024: Backing up VM XGTERPNext
Fri May  3 11:38:02 AM HKT 2024: XGTERPNext's state is: "running".
Fri May  3 11:38:02 AM HKT 2024: Shutting down the VM XGTERPNext
Fri May  3 11:38:02 AM HKT 2024: 1 loop(s) waiting for the VM XGTERPNext to shut down. Current state is "running"
Fri May  3 11:38:07 AM HKT 2024: XGTERPNext's state is: "poweroff".
Fri May  3 11:38:23 AM HKT 2024: VM XGTERPNext has been copied from /home/matth/VMs/XGTERPNext/ to /home/matth/temp/
At 88: USER=, LOGNAME=matth
WARNING: Environment variable LOGNAME or USER does not correspond to effective user id.
Waiting for VM "XGTERPNext" to power on...
VM "XGTERPNext" has been successfully started.
Fri May  3 11:38:23 AM HKT 2024: VM is started up again
At 98: USER=, LOGNAME=matth

因此我在该部分之前和之后添加了建议的打印输出,如下所示:

   echo "${cdt}: VM ${vm} has been copied from ${vmdir} to ${tempdir}" &>> $logfile
else
   err="not powered off"
   cdt=$(date)
   echo "${cdt}: Not exporting because the VM ${vm} is not powered off." &>> $logfile
fi
echo "At $LINENO: USER=$USER, LOGNAME=$LOGNAME" >> $logfile
if [[ $startup == 1 ]]; then
   vboxmanage startvm "$vm" --type headless &>> $logfile
   if [ $? -ne 0 ]; then
      err="starting up"
   else
      cdt=$(date)
      echo "${cdt}: VM is started up again" >> $logfile
   fi
fi
echo "At $LINENO: USER=$USER, LOGNAME=$LOGNAME" >> $logfile

当我在终端中手动运行脚本时,没有任何警告消息。当脚本通过 crontab 计划运行时,USER 为空,因此与 LOGNAME 不同。

此外,此警告消息自 4 月 27 日才出现,之前从未出现过。我不确定,但可能我在 4 月 26 日运行了更新,这改变了什么?

答案1

经过一些搜索经过反复试验,env USER=$LOGNAME在 cron 中在脚本名称前面设置使得警告消失。

所以我crontab -e现在的样子是这样的。

24 2 * * * env USER=$LOGNAME /home/matth/buprod.sh

与之前相比

24 2 * * * /home/matth/buprod.sh

感谢您的所有回复和评论。

相关内容