后台运行 sh -c

后台运行 sh -c

原始版本:

如何在后台运行 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选项来告诉sudolong-running command放到后台,而不是放入sudo后台:

sudo-b一些长时间运行的命令

或者

sudo-b sh-c'一些长时间运行的命令

哦!我差点忘了说!我的要求包括

  • 必须能够重定向输出long-running command保存到一个文件。
  • 必须能够捕获long-running command,大概是将其写入文件。
  • 必须能够以某种可靠的方式获取后台进程的 PID(而不需要grep通过 的输出ps)。

我怎样才能做到这一点?

答案1

  1. 首先,进程不是退出,而是停止。这是有区别的。
  2. 其次,它可能立即发生;您只是在按下之后才会收到通知Enter
  3. 第三,当您将命令放入后台时(使用&),它会将标准输入置于特殊状态,因此后台进程无法从键盘读取。当您将其放入sudo后台时,它无法读取密码,因此它会停止。
  4. 通过sudo将命令放入后台(而不是告诉登录 shell 放入sudo后台)来解决此问题:

    sudo -b sh -c 'app start'
    
  5. 对于像“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过程。

相关内容