"标准输入:是不是一个tty"来自的cronjob [英] "stdin: is not a tty" from cronjob

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

问题描述

我每次执行特定的cronjob时得到以下邮件。被调用的脚本,当我从cron直接甚至称它运行良好。所以我得到的消息是不是一个真正的错误,因为脚本不正是它应该做的。

下面是cron.d条目:

  * * * * *根/斌/ bash的-l -c/opt/get.sh>的/ tmp /文件

和get.sh脚本本身:

 #!/ bin / sh的#group和url
组=富URL =HTTPS://somehost.test/get.php组= $ {}组#加密
通过='吧'
方法=AES-256-XTS
通过= $(回声-n $通| XXD -ps | sed的'S / [[:xdigit:]] \\ {2 \\} /&安培/克)加密= $(wget的-qO- $ {URL})
德codeD = $(回声-n $加密| awk的-F'#''{$打印1})
IV = $(回声$加密| awk的-F'#''{$打印2}|的base64 --de code | XXD -ps | sed的'S / [[:xdigit:]] \\ {2 \\} /&安培/克')#的base64德code输入并保存到文件
输出= $(回声-n $德codeD |的base64 --de code | OpenSSL的ENC - $ {}方法-d -nosalt -nopad -K $ {}传递$ -IV IV {})如果[! -z$ {输出}];然后
        回声$ {}输出
其他
        回声错误而获取信息
科幻

当我不使用的bash -l <​​/ code>语法在wget的过程脚本挂起。所以我的猜测是,它是与wget和把输出到标准输出。但我不知道如何解决它。


解决方案

您实际上这里有两个问题。


  1. 为什么它打印标准输入:是不是一个tty

此警告消息是由的bash -l <​​/ code>打印。在 -l <​​/ code>( - 登录)的选项要求庆典启动登录shell,例如:当你输入你的密码通常是开始的那个。在这种情况下庆典预计其标准输入是一个真正的终端(如 isatty(0 )调用应该返回1),如果它是由的cron -hence此警告运行它是不正确的。

另一种简单的方法来重现此警告,很常见的一个,就是通过 SSH 来运行这个命令:

  $ SSH user@example.com'的bash -l -c回声测试'
密码:
标准输入:是不是一个tty
测试

这是因为 SSH 当一个命令作为参数调用不分配一个终端(应该使用 -t 选项 SSH 来强制在这种情况下,终端分配)。

<醇开始=2>
  • 为什么它没有工作没有 -l <​​/ code>?

  • 由于正确地@Cyrus在评论中指出,文件的列表,其中庆典负载在启动取决于会议的类型。例如。登录Shell将加载 / etc / profile文件〜/ .bash_profile中〜/ .bash_login文件〜/ .profile文件(参见手册 INVOCATION的bash(1) ),而对于非登录shell只会加载〜/ .bashrc中。看来你只能在加载登录shell的一个文件中定义的 HTTP_PROXY 变量,而不是在〜/ .bashrc中。你把它移动到〜/ .wgetrc ,这是正确的,但你也可以在〜/ .bashrc中定义它,它会奏效。

    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.

    Here is the cron.d entry:

    * *     * * *     root   /bin/bash -l -c "/opt/get.sh > /tmp/file"
    

    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
    

    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. Why it prints 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.

    Another easy way to reproduce this warning, and the very common one, is to run this command via ssh:

    $ ssh user@example.com '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).

    1. Why it did not work without -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.

    这篇关于&QUOT;标准输入:是不是一个tty&QUOT;来自的cronjob的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆