问题描述
每次执行特定的 cronjob 时,我都会收到以下邮件.当我直接甚至从 cron 调用它时,被调用的脚本运行良好.所以我得到的消息不是一个实际的错误,因为脚本完全按照它应该做的.
I'm getting the following mail every time I execute a specific cronjob. The called script runs fine when I'm calling it directly and even from cron. So the message I get is not an actual error, since the script does exactly what it is supposed to do.
这是 cron.d 条目:
Here is the cron.d entry:
* * * * * root /bin/bash -l -c "/opt/get.sh > /tmp/file"
和 get.sh 脚本本身:
and the get.sh script itself:
#!/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 和将输出放到 stdout 有关.但我不知道如何解决它.
When I'm not using the bash -l
syntax the script hangs during the wget process. So my guess would be that it has something to do with wget and putting the output to stdout. But I have no idea how to fix it.
推荐答案
您实际上在这里有两个问题.
You actually have two questions here.
- 为什么它打印
stdin: is not a tty
?
此警告消息由 bash -l
打印.-l
(--login
) 选项要求 bash
启动登录 shell,例如通常在您输入密码时启动的那个.在这种情况下,bash
期望它的 stdin
是一个真正的终端(例如 isatty(0)
调用应该返回 1),这不是真的如果它是由 cron
运行的——因此会出现这个警告.
This warning message is printed by bash -l
. The -l
(--login
) options asks bash
to start the login shell, e.g. the one which is usually started when you enter your password. In this case bash
expects its stdin
to be a real terminal (e.g. the isatty(0)
call should return 1), and it's not true if it is run by cron
—hence this warning.
重现此警告的另一种简单方法,也是非常常见的方法,是通过 ssh
运行此命令:
Another easy way to reproduce this warning, and the very common one, is to run this command via ssh
:
$ ssh [email protected] 'bash -l -c "echo test"'
Password:
stdin: is not a tty
test
发生这种情况是因为 ssh
在使用命令作为参数调用时没有分配终端(应该对 ssh
使用 -t
选项在这种情况下强制终端分配).
It happens because ssh
does not allocate a terminal when called with a command as a parameter (one should use -t
option for ssh
to force the terminal allocation in this case).
- 为什么没有
-l
它不起作用?
- Why it did not work without
-l
?
正如@Cyrus 在评论中正确指出的那样,bash
在启动时加载的文件列表取决于会话的类型.例如.对于登录 shell,它将加载 /etc/profile
、~/.bash_profile
、~/.bash_login
和 ~/.profile
(参见手册bash(1)
中的INVOCATION),而对于非登录shell,它只会加载~/.bashrc
.您似乎只在为登录 shell 加载的文件之一中定义了 http_proxy
变量,但未在 ~/.bashrc
中定义.你把它移到 ~/.wgetrc
并且它是正确的,但你也可以在 ~/.bashrc
中定义它,它会起作用.
As correctly stated by @Cyrus in the comments, the list of files which bash
loads on start depends on the type of the session. E.g. for login shells it will load /etc/profile
, ~/.bash_profile
, ~/.bash_login
, and ~/.profile
(see INVOCATION in manual bash(1)
), while for non-login shells it will only load ~/.bashrc
. It seems you defined your http_proxy
variable only in one of the files loaded for login shells, but not in ~/.bashrc
. You moved it to ~/.wgetrc
and it's correct, but you could also define it in ~/.bashrc
and it would have worked.
这篇关于“标准输入:不是 tty";来自定时任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!