Скрипт для выхода и перезапуска nautilus не работает

Как я указывал в своем вопросе о проблеме темы nautilus в 12.04 , я должен вводить 4 команды после каждого входа в систему в качестве обходного пути для проблемы с темами. Поскольку я не нашел реального решения, я решил поместить команды в сценарий, и я планирую сделать этот сценарий автоматически запускающимся, как только он заработает правильно. Команды:

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

И это мой сценарий:

#!/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

Мне пришлось использовать цикл и тестирование, так как в противном случае nautilus будет перезапущен до того, как он завершит работу, чтобы выйти. Но мой сценарий никогда не заканчивается. В то время как pgrep nautilus , введенный вручную в терминале, не возвращает никакого значения после nautilus -q , запуск скрипта возвращает бесконечный pid, поэтому скрипт не выполняется.

В чем моя ошибка? Откуда берется pid, когда команда запускается внутри скрипта?

И как я могу перезапустить nautilus из скрипта, избегая nautilus, чтобы навсегда заблокировать скрипт от дальнейшего выполнения? Строка nautilus -n запускает nautilus и сценарий зависает оттуда. Использование nautilus -n & amp; instetead приводит к выполнению сценария, но следующие команды выполняются до полного запуска nautilus, поэтому они не работают должным образом, настройки рабочего стола не применяются.

Есть ли другие идеи, чтобы справиться с этой надоедливой типизацией команд при каждом входе в систему?

2
задан 13 April 2017 в 15:25

1 ответ

Здесь есть несколько проблем. Давайте пройдемся по вашему сценарию.

  1. Вы пишете pid0=$(pgrep 'nautilus'), но потом проверяете переменную $pid (не $pid0). Я предполагаю, что вы вместо этого хотели написать

    pid=$(pgrep 'nautilus')
    
  2. Если я правильно понимаю, цель вашего цикла - остановить выполнение сценария до тех пор, пока $pid не станет пустым, то есть до [ 119] остановился. Действительно, команда nautilus -q отправит работающему приложению Nautilus сигнал на выход, но сама команда nautilus -q будет успешно завершена до того, как запущенное приложение Nautilus обработает этот сигнал и также успешно завершит себя. Таким образом, ваша идея использовать цикл для ожидания завершения работы приложения Nautilus верна. Тем не менее, этот цикл не работает бесконечно, как вы говорите. Запустите ваш скрипт с bash -x, чтобы увидеть, что происходит. Например, этот скрипт:

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

    ... при выполнении во время работы приложения Nautilus выдает следующий вывод:

    + 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!
    

    Как видите, цикл не бегать до бесконечности. В вашем случае, цикл вообще никогда не вводится из-за проблемы (1). Чтобы ответить на ваш вопрос Откуда берется pid, когда команда запускается внутри скрипта? - Pid приходит из запущенного приложения Nautilus. Причина, по которой вы не видите pid при запуске pgrep nautilus после nautilus -q из терминала , проста: вы недостаточно быстры. Время, которое вы тратите на ввод pgrep nautilus после запуска nautilus -q, достаточно, и когда вы наконец запускаете эту команду из терминала, приложение Nautilus уже давно завершилось; таким образом, вы не видите пид. Вы можете проверить это, набрав nautilus -q; pgrep nautilus (в виде одной команды) в терминале во время работы приложения Nautilus: тогда у вас есть хороший шанс увидеть pid.

  3. Косметика: в sleep 0 нет никакого смысла, и наличие в вашем скрипте pid=$(pgrep 'nautilus') дважды немного избыточно. Начните так:

    #!/bin/bash
    nautilus -q
    while [ -n "$(pgrep nautilus)" ]
    do :
    done
    
  4. Причина, по которой ваш сценарий не заканчивается, не является циклом: это команда nautilus -n. Поскольку эта команда не завершается (сама по себе), ваш скрипт просто зависает. Таким образом, вы должны запустить его в фоновом режиме, используя nautilus -n &. Поскольку по сценарию не существует простого способа определить, полностью ли запущен Nautilus, так что настройки рабочего стола будут применены (что мне известно ... за исключением некоторого уродливого стандартного кода, который попытается установить и прочитать фиктивные настройки рабочего стола в цикл, чтобы проверить это), проще всего, вероятно, просто установить подходящее время ожидания, которое будет работать для вас на практике, скажем, sleep 2.

Подводя итог , я ожидаю, что для вас будет работать следующее:

#!/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
0
ответ дан 13 April 2017 в 15:25

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

Похожие вопросы: