美文网首页
ssh执行远程命令的坑

ssh执行远程命令的坑

作者: yiduyangyi | 来源:发表于2018-02-01 21:29 被阅读281次

    要做的事情

    远程主机(your.host.com)上部署有docker,期望从本地开发机ssh到远程主机,在指定的容器中执行命令,基本命令如下:

    /usr/bin/ssh -i /home/users/yangjinfeng02/.ssh/.id_rsa  -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no -t rd@your.host.com "sudo docker exec -u rd -it 0284c4594aecc7689de407e8d2aa9106edaf646b000e3c362ad95f6dde5c9f0b bash -c 'pwd'"
    

    出现的问题

    登入shell终端,手动执行上面的命令,一切ok。但是放到crontab中无法执行,重定向输出到文件,得到如下信息

    Pseudo-terminal will not be allocated because stdin is not a terminal. 
    

    问题排查与解决

    注意到ssh命令中的-t参数,是用来控制给ssh分配伪终端。查看ssh帮助

    -T      Disable pseudo-tty allocation.
    
    -t      Force pseudo-tty allocation.  This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g., when implementing
                 menu services.  Multiple -t options force tty allocation, even if ssh has no local tty.
    

    注意到上述问题出错信息,结合ssh -t参数的含义,
    Multiple -t options force tty allocation, even if ssh has no local tty.
    可看出问题是在于分配终端引起的。

    使用 ssh -t -t 执行,发现crontab下运行正常,问题得以解决。

    延伸1——不分配伪终端

    既然是终端分配导致的,那么根据ssh -T参数的含义,是否可以disable伪终端的分配呢?可以进行试验,执行如下命令

    /usr/bin/ssh -i /home/users/yangjinfeng02/.ssh/.id_rsa  -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no -T rd@your.host.com "sudo docker exec -u rd -it 0284c4594aecc7689de407e8d2aa9106edaf646b000e3c362ad95f6dde5c9f0b bash -c 'pwd'"
    

    此时不管是命令行,还是crontab里,均无法运行。提示如下错误信息

    sudo: sorry, you must have a tty to run sudo
    

    出现该问题,是因为sudo命令必须在终端中执行。如果要突破该限制,需要修改/etc/sudoers,有两种选择

    1. Replace Defaults requiretty by Defaults !requiretty in your /etc/sudoers. This will impact your global sudo configuration.

    2. Alternatively, you can change this configuration at a per user, per group or per command basis

    Defaults!/path/to/my/bin !requiretty
    Defaults:myuser !requiretty
    

    延伸2——登录shell和非登录shell的区别

    直接在终端里执行shell命令,与crontab里执行,本质区别是二者环境变量的差异。

    登录shell将查找4个不同的启动文件来处理其中的命令。 bash shell处理文件的顺序如下:
    1:/etc/profile
    2:/etc/profile.d等待配置文件
    3:$HOME/.bash_profile 会加载$HOME/.bashrc和/etc/bashrc
    4:$HOME/.bash_login
    5:$HOME/.profile

    非登入shell则按如下顺序加载配置文件
    1:/etc/bashrc
    2:~/.bashrc

    相关文章

      网友评论

          本文标题:ssh执行远程命令的坑

          本文链接:https://www.haomeiwen.com/subject/ofpjzxtx.html