如何 sudo su;然后 运行 命令

How to sudo su; then run command

谁能帮我解决以下问题

我需要通过例如 ssh 连接到另一台服务器ubuntu 有权限的用户 运行 sudo su for sure 然后执行 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 的情况下它会以某种方式挂起并且不响应

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

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

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

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

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

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

但是,这并没有解决 sudo 启动的 shell 中 运行 pm2 的问题。 .

解决了这个问题

使用su-c选项指定命令

来自man su

In particular, an argument of -c will cause the next argument to be treated as a command by most command interpreters. The command will be executed by the shell specified in /etc/passwd for the target user.

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

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。添加在远程执行期间分配 TTY 的 -t 选项。

$ 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'