每次执行特定的 cronjob 时,我都会收到以下邮件。当我直接甚至从 cron 调用它时,被调用的脚本运行良好。所以我收到的消息并不是真正的错误,因为脚本完全按照它应该做的去做。
这是 cron.d 条目:
* * * * * root /bin/bash -l -c "/opt/get.sh > /tmp/file"
和 get.sh 脚本本身:
#!/bin/sh
#group and url
groups="foo"
url="https://somehost.test/get.php?groups=${groups}"
# encryption
pass='bar'
method='aes-256-xts'
pass=$(echo -n $pass | xxd -ps | sed 's/[[:xdigit:]]\{2\}/&/g')
encrypted=$(wget -qO- ${url})
decoded=$(echo -n $encrypted | awk -F '#' '{print $1}')
iv=$(echo $encrypted | awk -F '#' '{print $2}' |base64 --decode | xxd -ps | sed 's/[[:xdigit:]]\{2\}/&/g')
# base64 decode input and save to file
output=$(echo -n $decoded | base64 --decode | openssl enc -${method} -d -nosalt -nopad -K ${pass} -iv ${iv})
if [ ! -z "${output}" ]; then
echo "${output}"
else
echo "Error while getting information"
fi
当我不使用 bash -l
语法时,脚本会在 wget 进程中挂起。所以我的猜测是它与 wget 和将输出输出到标准输出有关。但我不知道如何修复它。
最佳答案
你实际上有两个问题。
- 为什么打印
stdin: is not a tty
?
此警告消息由 bash -l
打印。 -l
(--login
) 选项要求 bash
启动登录 shell,例如通常在您输入密码时启动的那个。在这种情况下,bash
期望它的 stdin
是一个真正的终端(例如 isatty(0)
调用应该返回 1),但事实并非如此如果它由 cron
运行——因此出现此警告。
重现此警告的另一种简单方法,也是最常见的方法,是通过 ssh
运行此命令:
$ ssh user@example.com 'bash -l -c "echo test"'
Password:
stdin: is not a tty
test
发生这种情况是因为 ssh
在使用命令作为参数调用时没有分配终端(应该为 ssh
使用 -t
选项在这种情况下强制终端分配)。
- 为什么没有
-l
就不能工作?
正如@Cyrus 在评论中正确指出的那样,bash
在启动时加载的文件列表取决于 session 的类型。例如。对于登录 shell,它将加载 /etc/profile
、~/.bash_profile
、~/.bash_login
和 ~/.profile
(请参阅手册 bash(1)
中的 INVOCATION),而对于非登录 shell,它将仅加载 ~/.bashrc
。您似乎只在为登录 shell 加载的文件之一中定义了您的 http_proxy
变量,而不是在 ~/.bashrc
中。您将它移动到 ~/.wgetrc
并且它是正确的,但您也可以在 ~/.bashrc
中定义它并且它会起作用。
关于linux - 来自定时任务的 "stdin: is not a tty",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26157703/