所以,我有这个shell脚本,动态构建另一个脚本并调用它(即一个嵌套脚本)。
这样的东西,我们称之为the_script.sh
:
#!/bin/sh
# do some stuff here, and create another script
./nested_script.sh
# do some other stuff, end
如果我只是调用./the_script.sh
,它会将所有内容输出到STDOUT,包括嵌套脚本的输出。
但是,如果它是从cronjob运行,就像这样:
0 8,12 * * 1-5 /home/myuser/the_script.sh >> /home/myuser/thescript.log
然后它不会输出嵌套脚本的结果,这对我来说非常重要。两个脚本的结果都是正确的,但它是运行的(从提示符或cron),并按预期运行。
有关为何发生这种情况以及如何预防的任何线索?
答案 0 :(得分:1)
在添加2>&1
0 8,12 * * 1-5 /home/myuser/the_script.sh >> /home/myuser/thescript.log 2>&1
然后它将显示类似: No such file or directory
的内容,这是因为当前工作目录不是shell的目录。最干净的是使用绝对路径,否则cd -- "$(dirname "${0:-.}")"
答案 1 :(得分:0)
cron不会从特定用户的主目录运行 - 因此运行./nested_script.sh可能无效。你应该指定这个的绝对路径,这样cron就知道它的确切位置。
答案 2 :(得分:0)
我向您推荐两个重要提示:
请注意,在nested_script.sh
或the_script.sh
主体中,是否有任何带有-i
或--interactive
参数的命令?如果是这样,则调用方外壳程序将为您执行一个交互式外壳程序,特别是带有附加的-t
或--tty
参数。因此,调用方外壳程序(crontab)必须从包含--tty的命令中捕获返回的STDOUT。但它无法处理,该命令的返回结果将失败。因此,您应尽可能删除-i or -t
选项。或者您需要更改脚本以避免使用-i or -t
。我以前解决过这样的麻烦。我这样写了一个cron时间表:
* * * * * /path/to/my-backup-script.sh
这是my-backup-script.sh正文
#!/bin/sh
docker exec -it my_cont mysqldump --user=myuser --password=dbpass my_db |gzip > /path/for/bk/my-backup.gz
我终于发现-it
参数是问题所在。因为shell想要将结果返回给cron,但失败了。
sshpass -p mypass command [options]
。在这种情况下,请仔细注意是否先在crontab env中定义了所需命令(包括在cron文件开头的PATH=/bin:/usr/bin: ...
中包含哪个命令返回结果)。第二,它不返回用户响应所需的值。例如 rm 命令可能会提示您确认删除。如果此类命令使用cron编写脚本,则该命令可以正常运行,但可能不会执行您想要的确切操作。