bash 来自 cronjob 的“标准输入:不是 tty”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26157703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"stdin: is not a tty" from cronjob
提问by Kai
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.
每次执行特定的 cronjob 时,我都会收到以下邮件。当我直接甚至从 cron 调用它时,被调用的脚本运行良好。所以我得到的消息不是一个实际的错误,因为脚本完全按照它应该做的。
Here is the cron.d entry:
这是 cron.d 条目:
* * * * * root /bin/bash -l -c "/opt/get.sh > /tmp/file"
and the get.sh script itself:
和 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 }')
iv=$(echo $encrypted | awk -F '#' '{print }' |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
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.
当我不使用bash -l
语法时,脚本会在 wget 过程中挂起。所以我的猜测是它与 wget 和将输出放到 stdout 有关。但我不知道如何解决它。
回答by afenster
You actually have two questions here.
你实际上有两个问题。
- Why it prints
stdin: is not a tty
?
- 为什么会打印
stdin: is not a tty
?
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.
此警告消息由 打印bash -l
。在-l
(--login
)选项要求bash
启动登录shell,例如在一个当你输入密码,这通常是开始。在这种情况下,bash
期望它stdin
是一个真正的终端(例如,isatty(0)
调用应该返回 1),如果它是由运行的,则它不是真的 - 因此cron
出现此警告。
Another easy way to reproduce this warning, and the very common one, is to run this command via ssh
:
重现此警告的另一种简单方法,也是非常常见的方法,是通过ssh
以下方式运行此命令:
$ ssh [email protected] 'bash -l -c "echo test"'
Password:
stdin: is not a tty
test
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).
发生这种情况是因为ssh
在使用命令作为参数调用时不分配终端(在这种情况下应该使用-t
选项ssh
来强制终端分配)。
- Why it did not work without
-l
?
- 为什么它没有工作
-l
?
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.
正如@Cyrus 在评论中正确指出的那样,bash
启动时加载的文件列表取决于会话的类型。例如,对于登录 shell,它将加载/etc/profile
, ~/.bash_profile
, ~/.bash_login
, 和~/.profile
(参见手册中的 INVOCATION bash(1)
),而对于非登录 shell,它只会加载~/.bashrc
. 似乎您http_proxy
只在为登录 shell 加载的文件之一中定义了变量,但不在~/.bashrc
. 你把它移到~/.wgetrc
并且它是正确的,但你也可以定义它~/.bashrc
并且它会起作用。
回答by user1130176
in your .profile, change
在您的 .profile 中,更改
mesg n
to
到
if `tty -s`; then
mesg n
fi
回答by Kai
I ended up putting the proxy configuration in the wgetrc. There is now no need to execute the script on a login shell anymore.
我最终将代理配置放在 wgetrc 中。现在不再需要在登录 shell 上执行脚本了。
This is not a real answer to the actual problem, but it solved mine.
这不是对实际问题的真正答案,但它解决了我的问题。
If you run into this problem check if you are getting all the environment variables set as you expect. Thanks to Cyrus for putting me to the right direction.
如果遇到此问题,请检查是否按照预期设置了所有环境变量。感谢赛勒斯把我带到正确的方向。