Сценарий Bash, который запускает процесс на 4 секунды, а затем убивает его не работает

У меня есть скрипт, который запускает Firefox на 4 секунды, а затем убивает его. Firefox автоматически войдет в плененный портал, поэтому мне нужно, чтобы он был открыт только в течение 4 секунд, как только Wi-Fi подключится. Я на Ubuntu 13.04.

Кажется, моя проблема в том, что $pid не установлен.

firefox ; pid=$!
sleep 4
kill $pid

РЕДАКТИРОВАТЬ: удален набор, и теперь он дает убить неверный PID.

5 ответов

Ваш скрипт не работает, потому что он ждет, пока процесс firefox не завершится, а затем выполнится pid=$! и другая команда.

Простой способ сделать то, что вы хотите, это timeout :

timeout 4s firefox

Он запускает программу, указанную после первого аргумента, и останавливает ее через время, указанное в качестве первого аргумента.

Причина твоя pid=$! не в том, что $! PID последнего задания, запущенного в фоновом режиме.

То есть,

$ foo & echo $!

начнет foo и повторить PID своего процесса.

В твоем случае, firefox ; pid=$! необходимо заменить на firefox & pid=$! но это может быть довольно бесполезно, потому что firefox это скрипт, который execфактический двоичный файл.

Что вам нужно сделать, это либо использовать killall (который попытается уничтожить все экземпляры Firefox, будь то ваши или других пользователей) или (скопировать и) отредактировать /usr/bin/firefox скрипт для отображения нового PID.

Еще несколько решений.

  • firefox & sleep 12; kill $! Красиво общий. Должен работать везде.
  • aptget install timeout а также timeout -k 3m 14s firefox (Я только что проверил один сервер Ubuntu и сервер FreeBSD. Ни один из них не был установлен по умолчанию).
  • использование expect как объяснено здесь: https://unix.stackexchange.com/questions/43340/how-to-introduce-timeout-for-shell-scripting
  • perl -e "alarm 10; exec @ARGV" "firefox"
  • $COMMAND 2>&1 >/dev/null & WPID=$!; sleep $TIMEOUT && kill $! & KPID=$!; wait $WPID ( Источник и объяснение)

Следуя нескольким подсказкам из других ответов, я придумал этот грязный скрипт:

firefox -no-remote -p c-portal &
ffpid=`ps aux | grep firefox | sed '2q;d' | tr -s ' ' | cut -d ' ' -f 2`
echo "firefox pid: $ffpid"
sleep 4
kill $ffpid

Мне также нужно было перейти к: конфигурации и изменения browser.sessionstore.resume_from_crash ложно.

Объяснение каждой команды: ps aux получает полный список процессов в системе, grep находит все те, которые содержат firefox, sed получает вторую строку (которая, как представляется, всегда является последним экземпляром firefox), tr удаляет лишние пробелы, вырезает получает второй столбец (-d означает разделитель, который является пробелом).

После этого беспорядка обработки строки есть отладочная вещь, которая печатает PID firefox, спит 4 секунды, чтобы он мог войти в систему, а затем убить firefox. Параметр about:config не позволяет восстановить сеанс.

Я не уверен, подходит ли это вашей ситуации, но вы могли бы использовать killall вместо kill, Так было бы:

firefox
sleep 4
killall firefox

Я думаю, что более правильный подход состоит в том, чтобы получить последний процесс Firefox, используя ps aux | grep firefox, но сегодня я не знаю, как это сделать, возвращая только этот наивысший номер процесса, используя скрипт bash.

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