我有一个脚本,其中一部分如下所示:

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 工作正常(我在日志中看到“正在加密 <文件>”),但文件未加密,并且 gpg 静默失败,没有 stdout/stderr 输出。

有什么线索吗?

有帮助吗?

解决方案

事实证明答案比我想象的要容易。有一个 --batch 缺少参数,gpg 尝试从 cron 作业不存在的 /dev/tty 中读取数据。调试我用过的 --exit-on-status-write-error 参数。但使用它时,我受到了 echoing 报告的退出状态 2 的启发 $? 正如 CD-Man 所建议的。

其他提示

在我的例子中,gpg 无法找到使用密钥的主目录:

GPG:无默认密钥:没有秘钥

GPG:0003608.cmd:签名+加密失败:没有秘钥

所以我添加了 --homedir /root/.gnupg. 。最终命令看起来像

回声'密码'| gpg -vvv -homedir/root/.gnupg - -batch - -passphrase -fd 0 -o -output/usr/share/file.gpg -encrypt -sign/usr/share/share/file.bz2

您应该确保 cronjob 运行时 GPG 在您的路径中。你最好的猜测是获取 GPG 的完整路径(通过这样做 which gpg)并使用完整路径运行它(例如 /usr/bin/gpp...).

其他一些调试技巧:

  • 输出的值 $? 运行 GPG 后(如下所示:回声“$?”)。这将为您提供退出代码,如果成功,该代码应该为 0
  • 将 STDERR 重定向到 GPG 的 STDOUT,然后将 STDOUT 重定向到文件,以检查可能打印的任何错误消息(您可以在命令行中执行此操作: /usr/bin/gpg ... 2>&1 >> gpg.log)

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

我曾经遇到过这个问题。

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

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

或者当 cron 执行时您尝试加密的文件实际上位于当前目录中?

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

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

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

需要改为:

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

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

就我而言:“GPG:解密失败:错误的会话密钥”。

尝试添加 /usr/bin/gpg、检查版本、设置 --batch、设置 --home (使用 /root/.gnupg 和 /home/user/.gnupg),但所有这些都不起作用。

/usr/bin/gpg -d --batch --homedir /home/ec2-user/.gnupg --no-mdc-warning -quiet --passphrase "$GPG_PP" "$file"

事实证明,AWS beanstalk 实例上的 cron 需要使用环境变量来设置 --passphrase $GPG_PP。现在的克朗:

0 15 * * * $(source /opt/elasticbeanstalk/support/envvars && /home/ec2-user/bin/script.sh >> /home/ec2-user/logs/cron_out.log 2>&1)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top