简体   繁体   English

如何 sudo su; 然后运行命令

[英]How to sudo su; then run command

Can anyone help me to to solve following issue谁能帮我解决以下问题

i need to ssh to another server by eg ubuntu user which has permission to run sudo su fore sure then execute pm2 restart command我需要通过例如ubuntu用户 ssh 到另一台服务器,该用户肯定有权运行 sudo su 然后执行 pm2 restart 命令

full command look like this完整的命令看起来像这样

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

for example i can run normally any command with sudo例如,我可以使用 sudo 正常运行任何命令

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

but with sudo su case it somehow hang and do not response但是使用sudo su案例它以某种方式挂起并且不响应

Unless you have an unusual setup, you can't normally string su with other preceding commands like that.除非您有一个不寻常的设置,否则您通常不能将su与其他类似的前面命令串连起来。 I would imagine it is running sudo su , then hanging in the root environment/session, because it's waiting for you to exit before preceding to the pm2 commands.我想它正在运行sudo su ,然后挂在根环境/会话中,因为它在pm2命令之前等待您退出。 Instead, I would consider something along the lines of this using the -c option:相反,我会使用-c选项考虑类似的事情:

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

As suggested in another answer, it would also probably be useful to encapsulate the $CMD variable in quotes in the ssh call.正如另一个答案中所建议的那样,将$CMD变量封装在ssh调用中的引号中也可能很有用。

Use -c option of su to specify the command使用su -c选项来指定命令

From man su来自man su

In particular, an argument of -c will cause the next argument to be treated as a command by most command interpreters.特别是, -c 的参数将导致大多数命令解释器将下一个参数视为命令。 The command will be executed by the shell specified in /etc/passwd for the target user.该命令将由 /etc/passwd 中为目标用户指定的 shell 执行。

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

You need to quote the expansion so that the entire string is parsed on the remote end.您需要引用扩展,以便在远程端解析整个字符串。

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

Otherwise, the expansion is subject to word splitting, and the remote shell gets a string which consists of the command sudo and the arguments su;否则,扩展会受到分词,远程 shell 会得到一个由命令sudo和参数su;组成的字符串su; , restart , 0; , restart , 0; , pm2 , restart; , pm2 , restart; , 1; , 1; , and exit; ,然后exit; . . That is, ssh will escape the semicolons when it builds a single string from the separate arguments you pass.也就是说,当ssh根据您传递的单独参数构建单个字符串时,它会转义分号。

However, that doesn't solve the problem of running pm2 in the shell started by sudo .但是,这并不能解决在sudo启动的 shell 中运行pm2的问题。 That is addressed by ramki .这由ramki解决。

su normally puts you in a sub shell which you can see by echoing the current PID (process id) su 通常会将您置于子 shell 中,您可以通过回显当前 PID(进程 ID)来查看该子 shell

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

But to get around this you can pipe the commands you want to run to su like this但是要解决这个问题,您可以像这样将要运行的命令通过管道传递给 su

$ echo "whoami" | sudo su
root

And we run multiple commands我们运行多个命令

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

Now to make this work with ssh现在用 ssh 来完成这项工作

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

Darn it, we need allocate a tty for the su command.该死,我们需要为 su 命令分配一个 tty。 Add the -t option which allocates a TTY during the remote execution.添加在远程执行期间分配 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

Your command would look this你的命令看起来像这样

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM