1

I have this little script I use to launch a root Nautilus window (yeah, dangerous, but sometimes necessary):

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

This works, but the System Monitor shows that until the root Nautilus is shut down, I have not only a root-owned nautilus process instance, but also root-owned gksudo, sudo, and xdg-open instances.

I would ideally like to have just the root nautilus instance running, which is what I thought the trailing ampersand in the command-line was supposed to do.

How do I get nautilus to detach properly? Can it be done at all?

4
  • The way I'd usually suggest is to use disown, which is a bash-builtin, but I'm not sure you can detach the process from gksudo.Thus: gksudo --description "..." -- bash -c "xdg-open / &; disown"
    – muru
    Sep 11, 2014 at 19:16
  • That command works too well: it does kill gksudo and xdg-open, but no root nautilus gets launched either.
    – Urhixidur
    Sep 12, 2014 at 13:25
  • The one in the comment or the ones in the answer? The comment has a syntax error.
    – muru
    Sep 12, 2014 at 13:26
  • The comment line. The syntax error would explain the lack of effect: gksudo goes through its motions, but the shelled-out command fails. Without the semi-colon, we get separate gksudo and xdg-open:nautilus processes, and the gksudo line does not return until nautilus is shut down. The 'disown' is redundant with the ampersand and is ignored, it seems.
    – Urhixidur
    Sep 12, 2014 at 15:59

2 Answers 2

2

Using the disown bash builtin, I can get xdg-open to detach from gksudo, but cannot do anything about nautilus:

The command:

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

The effect:

$ 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)

Unfortunately, this leaves the gksudo hanging around, doing nothing:

$ 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)

If you won't mind a hack, this script can get rid of the gksudo process, assuming you can type fast enough:

#! /bin/bash

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

If you can't type fast enough, adjust the sleep duration.

2
  • The processes detach from each other (in the sense that gksudo no longer is the parent of xdg-open), but nothing shuts down.
    – Urhixidur
    Sep 12, 2014 at 13:26
  • @Urhixidur I have already said as much, and given a workaround.
    – muru
    Sep 12, 2014 at 13:27
0

This is imperfect but close enough:

#!/bin/bash
set -e
gksudo --description "Launch a root Nautilus" -- \
   sh -c "echo 'Password accepted'"
gksudo -- sh -c "xdg-open / &" &
PID_GKSUDO=`pgrep -n gksudo`
sleep 10
PID_XDGOPEN=`pgrep -u root -n xdg-open`
sudo kill $PID_XDGOPEN $PID_GKSUDO
exit 0

Some explanations:

set -e

This ensures the script exits if the user cancels out of the password prompt or if anything else fails.

gksudo --description "Launch a root Nautilus" -- \
   sh -c "echo 'Password accepted'"

This line won't return until the user has entered the password or cancelled out of the prompt. The echo command is inoccuous and just makes for nice feedback when the script is run from a command line.

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

The gksudo ... & returns right away (because it detaches from the script process), regardless of an eventual password prompt. This is why we prompted for the password on the previous line, because we otherwise can't tell how long we'll need to sleep later.

Note also that the xdg-open / & will also detach from gksudo, so we end up with two orphans: gksudo (childless) and xdg-open (parent of the desired root nautilus process).

PID_GKSUDO=`pgrep -n gksudo`
sleep 10

Here we recover the xdg-open process ID (immediately available) and then wait for nautilus-gdu to initialize and the window to appear. If we did not wait, the next PID-fetching command would fail because the process wouldn't exist yet (pgrep would return an error 1 and the script would not proceed to the kill line).

PID_XDGOPEN=`pgrep -u root -n xdg-open`
sudo kill $PID_XDGOPEN $PID_GKSUDO
exit 0

Finally, we get the xdg-open PID and kill the useless processes before exiting the script.

2
  • Thanks for the attempts to help. I did not know of 'disown' before.
    – Urhixidur
    Sep 12, 2014 at 15:51
  • Umm...On further testing, the above works, but only if invoked from a command line. If run from the GUI, there is no longer a shared environment, which means every gksudo invocation will ask for the password. I can go as far as subordinating the second gksudo invocation to the first (by moving its command line into the first gksudo's sh argument using () && ()), a really ugly kludge. But trying to chain the later kill invocations in the same way runs into other problems. Time to give up.
    – Urhixidur
    Sep 12, 2014 at 20:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .