本文介绍了“标准输入:不是 tty";来自定时任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每次执行特定的 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.

  1. 为什么它打印 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).

  1. 为什么没有 -l 它不起作用?
  1. 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";来自定时任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 00:46