我有这个小脚本,用于启动根 Nautilus 窗口(是的,很危险,但有时是必要的):
#!/bin/bash
gksudo --description "Launch a root Nautilus" -- sh -c "xdg-open / &"
这可行,但系统监视器显示,直到关闭根 Nautilus 为止,我不但拥有根拥有的 nautilus 进程实例,而且还拥有根拥有的 gksudo、sudo 和 xdg-open 实例。
我理想情况下只想运行根 nautilus 实例,这就是我认为命令行中尾随的 & 符号应该做的事情。
如何让 nautilus 正确分离?可以做到吗?
答案1
使用disown
bash 内置,我可以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-open
PID和无用的进程。kill