linux - 来自定时任务的 "stdin: is not a tty"

标签 linux bash cron crontab

每次执行特定的 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 和将输出输出到标准输出有关。但我不知道如何修复它。

最佳答案

你实际上有两个问题。

  1. 为什么打印 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 选项在这种情况下强制终端分配)。

  1. 为什么没有 -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/

相关文章:

linux - linux什么时候设置电脑的正确时间?

php - Linux 的 cron 是异步的还是同步的?

linux - Linux 上的 netcat 代理 shell 问题

c - 关于实用程序 'df' 中的库 <libutil.h>,Linux

linux - 编辑器中的终端编辑命令

bash - "echo"和 "echo -n"有什么区别?

linux - 未找到软链接(soft link),即使它明显存在

spring - Cron 表达式必须包含 6 个字段(在 "#{systemEnvironment[' db_cron']} 中找到 1 个)

linux - 如何在 C 代码中从其中一个进程触发时重新启动一组进程

java - 如何从命令行生成 Java 文件的串行版本 UID?