【问题标题】:How to sudo su; then run command如何 sudo su;然后运行命令
【发布时间】:2019-12-22 22:09:52
【问题描述】:

谁能帮我解决以下问题

我需要通过 ssh 连接到另一台服务器,例如ubuntu 有权运行 sudo su 肯定 然后执行 pm2 restart 命令的用户

完整的命令如下所示

#!/bin/sh
CMD="sudo su; pm2 restart 0; pm2 restart 1; exit;"  
ssh -i somepemfile.pem ubuntu@1.1.1.1 $CMD

例如,我可以使用 sudo 正常运行任何命令

CMD="sudo /etc/init.d/apache2 restart"  

但在 sudo su 的情况下,它会以某种方式挂起并且不响应

【问题讨论】:

    标签: bash sudo pm2


    【解决方案1】:

    您需要引用扩展,以便在远程端解析整个字符串。

    ssh -i somepemfile.pem ubuntu@1.1.1.1 "$CMD"
    

    否则,扩展会被分词,远程shell会得到一个字符串,该字符串由命令sudo和参数su;restart0;pm2restart;组成、1;exit;。也就是说,ssh 在从您传递的单独参数构建单个字符串时将转义分号。

    但是,这并不能解决在sudo 启动的shell 中运行pm2 的问题。 ramki 解决了这个问题。

    【讨论】:

      【解决方案2】:

      su 通常会将您置于一个子 shell 中,您可以通过回显当前 PID(进程 ID)来查看它

      $ echo $$
      94260
      $ sudo echo $$
      94260
      $ sudo su
      $ echo $$
      94271
      

      但是要解决这个问题,您可以像这样将要运行的命令通过管道传递给 su

      $ echo "whoami" | sudo su
      root
      

      我们运行多个命令

      $ echo "uptime;whoami" | sudo su
      11:29  up 8 days, 19:20, 4 users, load averages: 4.55 2.96 2.65
      root
      

      现在用 ssh 来实现这个功能

      $ ssh wderezin@localhost 'echo "uptime;whoami" | sudo su'
      sudo: no tty present and no askpass program specified
      

      该死,我们需要为 su 命令分配一个 tty。添加 -t 选项,在远程执行期间分配 TTY。

      $ ssh -t wderezin@localhost 'echo "uptime;whoami" | sudo su'
      11:36  up 8 days, 19:26, 5 users, load averages: 2.97 2.97 2.76
      root
      

      你的命令看起来像这样

      ssh -i somepemfile.pem ubuntu@1.1.1.1 'echo "pm2 restart 0; pm2 restart1" | sudo su'
      
      

      【讨论】:

        【解决方案3】:

        除非您有不寻常的设置,否则您通常不能将su 与前面的其他类似命令串起来。我想它正在运行sudo su,然后挂在根环境/会话中,因为它在执行pm2 命令之前等待您退出。相反,我会考虑使用-c 选项:

        CMD="sudo su -c 'pm2 restart 0; pm2 restart 1'"
        ssh -i somepemfile.pem ubuntu@1.1.1.1 "$CMD"
        

        正如另一个答案中所建议的,将$CMD 变量封装在ssh 调用中的引号中也可能很有用。

        【讨论】:

          【解决方案4】:

          使用su-c 选项来指定命令

          来自man su

          特别是, -c 的参数将导致下一个参数被大多数命令解释器视为命令。该命令将由指定的 shell 执行 目标用户的 /etc/passwd。

          CMD="sudo su -c  \"pm2 restart 0; pm2 restart 1;\""
          

          【讨论】:

            相关资源