如何从cron运行的脚本中运行gpg?

时间:2020-03-05 18:46:33  来源:igfitidea点击:

我有一个脚本,该脚本的一部分看起来像这样:

for file in `ls *.tar.gz`; do
  echo encrypting $file
  gpg --passphrase-file /home/$USER/.gnupg/backup-passphrase \
    --simple-sk-checksum -c  $file
done

由于某种原因,如果我手动运行此脚本,则可以正常工作,并且所有文件都已加密。如果我将其作为cron作业运行,则echo $ file可以正常工作(我在日志中看到" encrypting <file>"),但是该文件未得到加密,gpgsilent失败,没有stdout / stderr输出。

有什么线索吗?

解决方案

回答

确保正在运行cron作业的用户具有加密文件所需的权限。

回答

我曾经遇到过这个问题。

我真的不能告诉你为什么,但是我不认为cron使用与用户相同的环境变量来执行。

实际上,我必须导出良好的路径以使我的程序正常执行。
gpg至少要尝试执行吗?

还是在执行cron时实际上要在当前目录中插入的文件?

也许尝试在脚本中执行echo whereis gpgecho $ PATH看看它是否包含在内...为我工作。

回答

当cronjob运行时,我们应确保GPG在路径中。最好的猜测是获取GPG的完整路径(通过执行"哪一个gpg")并使用完整路径(例如" / usr / bin / gpp ...")运行它。

其他一些调试技巧:

  • 在运行GPG后输出" $?"的值(例如:echo" $?")。这将为我们提供退出代码,如果成功,则应为0
  • 将STDERR重定向到GPG的STDOUT,然后将STDOUT重定向到文件,以检查可能打印的任何错误消息(我们可以在命令行执行此操作:/ usr / bin / gpg ... 2>&1 >> gpg。日志)

回答

事实证明,答案比我预期的要容易。缺少一个--batch参数,gpg会尝试从/ dev / tty中读取cron作业不存在的参数。为了调试,我使用了" --exit-on-status-write-error"参数。但是使用它,我受到了退出状态2的启发,退出状态是Cd-Man建议的,通过回显" $?"来报告。

回答

@skinp Cron作业由sh执行,而大多数现代Unix使用bash或者ksh进行交互式登录。 (根据我的经验)最大的问题是sh无法理解以下内容:

export PS1='\u@\h:\w> '

需要更改为:

PS1='\u@\h:\w> '
export PS1

因此,如果cron运行使用第一种语法定义环境变量的shell脚本,则在运行其他命令之前,该其他命令将永远不会执行,因为sh炸开了试图定义变量的尝试。