Ask Ubuntu is a question and answer site for Ubuntu users and developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

As I pointed out in my question nautilus theme problem in 12.04 I have to type 4 commands after every logon as workaround for a theming problem. Since I didn't find a real solution I decided to put the commands into a script and my plan ist to make this script autostart once it works properly. The commands are:

nautilus -q
nautilus -n &
gsettings set org.gnome.desktop.background show-desktop-icons false
gsettings set org.gnome.desktop.background show-desktop-icons true

And this is my script:

#!/bin/bash
nautilus -q
pid0=$(pgrep 'nautilus')
while [ -n "$pid" ];
do
  pid=$(pgrep 'nautilus')
  sleep 0
done
nautilus -n
gsettings set org.gnome.desktop.background show-desktop-icons false
gsettings set org.gnome.desktop.background show-desktop-icons true
exit 0

I had to use the loop and testing since otherwise nautilus is restarted before it has finished to quit itself. But my script never ends. While pgrep nautilus entered manually in a terminal doesn't return any value after nautilus -q, runing the script returns endless a pid so the script isn't executed.

What is my mistake? Where does the pid come from when the command is run within the script?

And how can I restart nautilus from within the script avoiding nautilus to block the script forever from further execution? The line nautilus -n starts nautilus and the script hangs from there on. Using nautilus -n & instetead makes the script run, but the follwing commands are executed before nautilus has completely started so they dont't work as intended, desktop settings are not applied.

Are there any other ideas to cope with this annoying command-typing at every logon?

share|improve this question

There are several problems here. Let's walk through your script.

  1. You write pid0=$(pgrep 'nautilus'), but test the variable $pid (not $pid0) afterwards. I assume you meant to instead write

    pid=$(pgrep 'nautilus')
    
  2. If I understand correctly, the intention of your loop is to stall execution of the script until $pid is empty, i.e., until nautilus has stopped running. Indeed, the command nautilus -q will send a running Nautilus application the signal to quit, but the command nautilus -q itself will already have succesfully terminated before the running Nautilus application has processed that signal and successfully terminated itself also. Thus, your idea of using a loop in order to wait for the Nautilus application to terminate is valid. However, that loop does not run indefinitely as you say. Run your script with bash -x in order to see what happens. For example, this script:

    #!/bin/bash -x
    nautilus -q
    pid=$(pgrep 'nautilus')
    while [ -n "$pid" ];
    do
      pid=$(pgrep 'nautilus')
      sleep 0
    done
    echo "Nautilus has stopped running!"
    

    ...when executed while a Nautilus application is running, gives me the following output:

    + nautilus -q
    ++ pgrep nautilus
    + pid=24602
    + '[' -n 24602 ']'
    ++ pgrep nautilus
    + pid=24602
    + sleep 0
    + '[' -n 24602 ']'
    ++ pgrep nautilus
    + pid=24602
    + sleep 0
    + '[' -n 24602 ']'
    ++ pgrep nautilus
    + pid=24602
    + sleep 0
    + '[' -n 24602 ']'
    ++ pgrep nautilus
    + pid=24602
    + sleep 0
    + '[' -n 24602 ']'
    ++ pgrep nautilus
    + pid=
    + sleep 0
    + '[' -n '' ']'
    + echo 'Nautilus has stopped running!'
    Nautilus has stopped running!
    

    As you see, the loop does not run indefinitely. In your case, the loop is never even entered in the first place, because of problem (1). To answer your question Where does the pid come from when the command is run within the script? -- The pid comes from the running Nautilus application. The reason that you do not see a pid when running pgrep nautilus after nautilus -q from the Terminal is simple: You're not fast enough. The time you take to type pgrep nautilus after you have run nautilus -q is plenty, and when you finally run that command from the terminal, the Nautilus application has already terminated long ago; thus you do not see a pid. You can check this by typing nautilus -q; pgrep nautilus (as a single command) in the terminal while a Nautilus application is running: You have a good chance of seeing a pid then.

  3. Cosmetic: There is no point in sleep 0, and having pid=$(pgrep 'nautilus') twice in your script is a bit redundant. Start like this:

    #!/bin/bash
    nautilus -q
    while [ -n "$(pgrep nautilus)" ]
    do :
    done
    
  4. The reason that your script does not end is another than the loop: It is the command nautilus -n. Since this command does not terminate (by itself), your script just hangs. So you do have to run it in the background using nautilus -n &. As there is no easy way to determine from the script whether Nautilus has "completely started" such that desktop settings will apply (that I know of... save for some ugly boilerplate code that will try to set and read a dummy desktop setting in a loop in order to check that), the easiest thing is probably to just set an appropriate waiting time that will work for you in practice, say, sleep 2.

Summing up, I expect the following to work for you:

#!/bin/bash

nautilus -q
while [ -n "$(pgrep nautilus)" ]
do :
done

nautilus -n &
sleep 2
gsettings set org.gnome.desktop.background show-desktop-icons false
gsettings set org.gnome.desktop.background show-desktop-icons true
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.