如何正确分离命令?

如何正确分离命令?

我有这个小脚本,用于启动根 Nautilus 窗口(是的,很危险,但有时是必要的):

#!/bin/bash
gksudo --description "Launch a root Nautilus" -- sh -c "xdg-open / &"

这可行,但系统监视器显示,直到关闭根 Nautilus 为止,我不但拥有根拥有的 nautilus 进程实例,而且还拥有根拥有的 gksudo、sudo 和 xdg-open 实例。

我理想情况下只想运行根 nautilus 实例,这就是我认为命令行中尾随的 & 符号应该做的事情。

如何让 nautilus 正确分离?可以做到吗?

答案1

使用disownbash 内置,我可以xdg-open从中分离gksudo,但无法对执行任何操作nautilus

命令:

gksudo --description "Launch a root Nautilus" -- bash -c "xdg-open / & disown"

效果:

$ pstree -ps $(pgrep -u root nautilus)
init(1)───lightdm(1095)───lightdm(1537)───init(1545)───xdg-open(29323)───nautilus(29376)─┬─{nautilus}(29378)
                                                                                         ├─{nautilus}(29380)
                                                                                         ├─{nautilus}(29381)
                                                                                         └─{nautilus}(29382)

不幸的是,这会导致程序gksudo挂起,什么也不做:

$ pstree -ps $(pgrep gksudo)
init(1)───lightdm(1095)───lightdm(1537)───init(1545)───test.sh(29601)───gksudo(29604)─┬─{gksudo}(29605)
                                                                                      ├─{gksudo}(29606)
                                                                                      ├─{gksudo}(29608)
                                                                                      └─{gksudo}(29610)

如果你不介意被黑客攻击,这个脚本可以摆脱这个gksudo过程,假设你的打字速度足够快:

#! /bin/bash

gksudo --description "Launch a root Nautilus" -- bash -c "xdg-open / & disown; exit" &
sleep 10; kill %1

如果您打字速度不够快,请调整sleep持续时间。

答案2

这虽然不完美,但也足够接近了:

/bin/bash #!/bin/bash
设置-e
gksudo --description "启动根 Nautilus" -- \
   sh -c“echo‘密码已接受’”
gksudo --sh -c "xdg-open /&" &
PID_GKSUDO=`pgrep -n gksudo`
睡 10
PID_XDGOPEN=`pgrep -u root -n xdg-open`
sudo 杀死 $PID_XDGOPEN $PID_GKSUDO
出口 0

一些解释:

设置-e

这确保当用户取消密码提示或其他任何失败时脚本退出。

gksudo --description "启动根 Nautilus" -- \
   sh -c“echo‘密码已接受’”

直到用户输入密码或取消提示后,此行才会返回。该echo命令无害,只是在从命令行运行脚本时提供良好的反馈。

gksudo --sh -c "xdg-open /&" &

无论最终是否提示输入密码,都会立即返回gksudo ... &(因为它脱离了脚本进程)。这就是我们在上一行提示输入密码的原因,因为否则我们就无法知道稍后需要休眠多长时间。

还要注意,xdg-open / &也将与分离gksudo,因此我们最终会得到两个孤儿:(gksudo无子进程)和xdg-open(所需根进程的父进程nautilus)。

PID_GKSUDO=`pgrep -n gksudo`
睡 10

这里我们恢复xdg-open进程 ID(立即可用),然后等待nautilus-gdu初始化并出现窗口。如果我们不等待,下一个 PID 获取命令将失败,因为进程尚不存在(pgrep将返回错误 1,并且脚本不会继续执行该kill行)。

PID_XDGOPEN=`pgrep -u root -n xdg-open`
sudo 杀死 $PID_XDGOPEN $PID_GKSUDO
出口 0

最后,我们在退出脚本之前获得了xdg-openPID和无用的进程。kill

相关内容