我有以下 cron 作业/etc/cron.d/backup
:
*/1 * * * * backupbot /home/backupbot/bin/backup-script.sh
基本上,我希望backup-script.sh
每分钟运行一次(并且用户备份机器人应该执行该作业)。
该/home/backupbot/bin/backup-script.sh
文件的所有者是备份机器人(并且他拥有“x”权限)。该文件如下所示:
#!/bin/bash
set -e
{
BACKUP_DIR=/var/app/backups
STORAGE_ACCOUNT_URL=https://myserver/backups
BACKUP_FILE=$(ls $BACKUP_DIR -t | head -1)
if [ -z "$BACKUP_FILE" ]; then
echo "There are no backups to synchronize"
exit 0
fi
azcopy login --identity
azcopy copy $BACKUP_DIR/$BACKUP_FILE $STORAGE_ACCOUNT_URL/$BACKUP_FILE
} >/tmp/cron.backup-script.$$ 2>&1
通常,任何输出都应记录到/tmp/cron.backup-script.xxxx
.这样的文件永远不会被创建。
Cron 注意到该作业的唯一证据是以下输出systemctl status cron.service
:
● cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2021-04-13 09:59:08 UTC; 6h ago
Docs: man:cron(8)
Main PID: 1086 (cron)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/cron.service
└─1086 /usr/sbin/cron -f
Apr 13 16:00:01 my-vm CRON[17201]: pam_unix(cron:session): session closed for user root
Apr 13 16:00:01 my-vm CRON[17198]: pam_unix(cron:session): session closed for user root
Apr 13 16:00:01 my-vm CRON[17199]: pam_unix(cron:session): session closed for user root
Apr 13 16:01:01 my-vm CRON[17402]: pam_unix(cron:session): session opened for user root by (uid=0)
Apr 13 16:01:01 my-vm CRON[17403]: (root) CMD ([ -f /etc/krb5.keytab ] && [ \( ! -f /etc/opt/omi/creds/omi.keytab \) -o \( /etc/krb5.keytab -nt /etc/opt/omi/creds/omi.keytab \) ] &&
Apr 13 16:01:01 my-vm CRON[17401]: pam_unix(cron:session): session opened for user backupbot by (uid=0)
Apr 13 16:01:01 my-vm CRON[17404]: (backupbot) CMD (/home/backupbot/bin/backup-script.sh)
Apr 13 16:01:01 my-vm CRON[17402]: pam_unix(cron:session): session closed for user root
Apr 13 16:01:01 my-vm CRON[17401]: (CRON) info (No MTA installed, discarding output)
Apr 13 16:01:01 my-vm CRON[17401]: pam_unix(cron:session): session closed for user backupbot
它提到了一些关于会话的内容备份机器人。我怎样才能进一步调查?
答案1
根据评论,脚本是仅有的由所有者可执行。即,它不可读。这会阻止所有者执行脚本。
例子:
$ chmod 500 script
$ ls -l script
-r-x------ 1 myself myself 24 Apr 14 09:21 script
$ ./script
hello
$ chmod 100 script
$ ls -l script
---x------ 1 myself myself 24 Apr 14 09:21 script
$ ./script
/bin/bash: ./script: Permission denied
如果脚本文件不可读,则bash
shell 解释器(以当前用户身份运行)无法读取它。
使脚本可执行且可读。
除了上述之外,还可以考虑使用变量扩展的正确双引号, 和不解析来自的输出ls
(只有真正有用的是看着)。
您的脚本已修改:
#!/bin/bash
backup_dir=/var/app/backups
storage_account_url=https://myserver/backups
{
# Find most recently modified file in "$backup_dir".
# Assumes that there are only files there, no subdirectories.
set -- "$backup_dir"/*
backup_file_path=$1
shift
for pathname do
if [ "$pathname" -nt "$backup_file_path" ]; then
backup_file_path=$pathname
fi
done
if [ ! -e "$backup_file_path" ]; then
echo 'There are no backups to synchronize'
exit 1
fi
# Perform backup.
azcopy login --identity || exit 1
azcopy copy "$backup_file_path" "$storage_account_url/$(basename "$backup_file_path")"
} >/tmp/cron.backup-script.$$ 2>&1
答案2
通过cron
、 或at
、 或运行的作业batch
不会在桌面上的同一运行时环境中运行。您的任何PATH
更改或其他环境变量设置都不会自动传播到您的cron
作业。例如,没有$DISPLAY
,因此 GUI 程序需要特殊处理(读取man xhost
)。
可以在Read 文件cron
中为所有作业设置环境变量。crontab
man 5 crontab
echo "=== set ===";set;echo "=== env ===";env | sort;echo "=== alias ===";alias
查看每个环境中的结果 。
由于默认情况下,command
该行的部分由 解释,它的语法比 更简单,因此我建议调用一个脚本(可执行文件,已安装,以 开头)来设置环境,然后调用所需的程序。crontab
/bin/sh
/bin/bash
command
bash
#!/bin/bash
在通过, ,运行的脚本中始终使用绝对路径(从/
根目录开始的路径)。cron
at
batch