Как правильно отсоединить команду?

У меня есть небольшой скрипт, который я использую для запуска корневого окна Nautilus (да, опасно, но иногда необходимо):

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

Это работает, но системный монитор показывает, что до закрытия корневого Nautilus у меня есть не только экземпляр процесса nautilus, принадлежащий пользователю root, но также экземпляры gksudo, sudo и xdg-open, принадлежащие пользователю root.

В идеале мне бы хотелось, чтобы был запущен только корневой экземпляр nautilus, что, как я думал, должен был выполнять конечный амперсанд в командной строке.

Как заставить наутилус правильно отсоединиться? Можно ли это сделать вообще?

2 ответа

С использованием 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 продолжительность.

Это несовершенно, но достаточно близко:

#! / Bin/ Баш
установить -е
gksudo - описание "Запустите рут Наутилус" - \
   sh -c "echo 'Пароль принят'"
gksudo - sh -c "xdg-open / &" &
PID_GKSUDO=`pgrep -n gksudo`
спать 10
PID_XDGOPEN=`pgrep -u root -n xdg-open`
sudo kill $PID_XDGOPEN $PID_GKSUDO
выход 0

Некоторые объяснения:

установить -е

Это гарантирует, что сценарий завершится, если пользователь отменяет запрос пароля или что-либо еще не удается.

gksudo - описание "Запустите рут Наутилус" - \
   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 идентификатор процесса (сразу же доступен), а затем ждать nautilus-gdu инициализировать и появиться окно. Если бы мы не подождали, следующая команда PID-fetching потерпела бы неудачу, потому что процесс еще не существовал (pgrep вернет ошибку 1 и скрипт не перейдет к kill линия).

PID_XDGOPEN = `pgrep -u root -n xdg-open`
sudo kill $ PID_XDGOPEN $ PID_GKSUDO
выход 0

Наконец, мы получаем xdg-open PID и kill бесполезные процессы перед выходом из скрипта.

Другие вопросы по тегам