原始版本:
如何在后台运行 sudo sh -c“命令”
在终端中
sudo sh -c“命令”&在后台启动,但只要我按下回车键,进程就会退出
[test@localhost app]$ sudo sh -c 'app start' &
[3] 31725
[test@locahost app]$
[3]+ Stopped sudo sh -c 'app start'
改写:
我想跑some long-running command
在后台以 root 身份运行。“显而易见”的方法是
须藤一些长时间运行的命令&
出于不明原因,我也尝试过
sudo sh-c'一些长时间运行的命令' &
这两个命令都以同样的方式失败了:我得到了一个 shell 提示符,但是,当我点击 时Enter,我收到了一条错误消息:
$ sudo sh -c '一些长时间运行的命令' & [3] 31725 $ [3]+ 已停止 sudo sh -c '一些长时间运行的命令‘ $
有人向我指出,当我sudo
像这样将命令放入后台时,它将失去对标准输入的访问权限。因此,它无法读取密码,并且在尝试时会停止。
另一种方法是使用-b
选项来告诉sudo
将long-running command
放到后台,而不是放入sudo
后台:
sudo-b一些长时间运行的命令
或者
sudo-b sh-c'一些长时间运行的命令‘
哦!我差点忘了说!我的要求包括
- 必须能够重定向输出
long-running command
保存到一个文件。 - 必须能够捕获
long-running command
,大概是将其写入文件。 - 必须能够以某种可靠的方式获取后台进程的 PID(而不需要
grep
通过 的输出ps
)。
我怎样才能做到这一点?
答案1
- 首先,进程不是退出,而是停止。这是有区别的。
- 其次,它可能立即发生;您只是在按下之后才会收到通知Enter。
- 第三,当您将命令放入后台时(使用
&
),它会将标准输入置于特殊状态,因此后台进程无法从键盘读取。当您将其放入sudo
后台时,它无法读取密码,因此它会停止。 通过
sudo
将命令放入后台(而不是告诉登录 shell 放入sudo
后台)来解决此问题:sudo -b sh -c 'app start'
对于像“app start”这样的简单命令,显然不需要
sh -c
。尝试sudo -b 'app start'
PS 这个问题其实与 无关sh -c
。您可能会遇到类似的问题
sudo sleep 42 &
答案2
以下是几种方法:
sudo sh -c '(一些长时间运行的命令> out.txt; 回显 $? > ret.txt)& 回显 $!'
和
sudo -b sh -c 'echo $$ > pid.txt;一些长时间运行的命令> out.txt; 回显 $? > ret.txt'
一个稍微棘手的方法:
sudo sleep 0 sudo sh -c'echo $$ > pid.txt;一些长时间运行的命令> out.txt; 回显 $? > ret.txt' &
其中sudo sleep 0
要求您输入密码并缓存您的凭据,因此下一个sudo
命令可以继续而无需输入您的密码。
所有这些都会给你sh -c
进程的 PID,而不是long-running command
过程。