Файловые дескрипторы принадлежат процессу: то есть текущему процессу. Сразу после выхода из процесса назначения не действуют. Даже подоболочка (или любой дочерний процесс), наследующая файловые дескрипторы, из fork () вызывает свои собственные копии файловых дескрипторов (файловый дескриптор - это просто число, указывающее на ресурс ввода-вывода в ядре Linux). Это похоже на открытые файлы - открытие файла в одном процессе не делает его открытым для всех, и если вы не закроете его самостоятельно, Linux закроет его и очистит, когда процесс завершится.
Вы должны контролировать статус завершения процесса pgrep, который будет находиться в $? Переменная. Или проверьте, является ли переменная $status, в которой вы сохраняете вывод pgrep, f.e. строка ненулевой -длины. Скрипт в вопросе проверяет, равна ли строка в статусе переменной «1»
так
#!/bin/bash
pgrep compton >/dev/null
if [[ $? -eq 0 ]]
then
killall compton
else
exec compton -b
fi
или
#!/bin/bash
status=$(pgrep compton 2>&1)
if [[ -n "$status" ]]
then
killall compton
else
exec compton -b
fi
Вы получаете вывод pgrep
в свою status
переменную. Это просто не тот результат, которого вы ожидаете.
pgrep
выводит идентификаторы процессов (PID )процессов, соответствующих заданному шаблону. Если есть процесс, имя которого соответствует compton
, то $status
будет PID этого процесса или этих процессов. pgrep
также возвращает статус выхода, но статус выхода не фиксируется подстановкой команды в виде строки.
В своем тесте вы сравниваете $status
с 1
. Маловероятно, что compton
имеет PID 1.
Если вы хотите убить любой compton
процесс, если он существует, и запустить compton -b
, если compton
процесса не существует, вы можете сделать это с помощью
#!/bin/sh
if ! pkill compton; then
exec compton -b
fi
Здесь используется статус выхода pkill
. Инструмент pkill
работает аналогичноpgrep
(они обычно распространяются и устанавливаются как пара ), но вместо вывода PID соответствующих процессов, как это делал бы pgrep
, pkill
отправляет сигнал TERM
(по умолчанию )для соответствующих процессов.
Ключевое слово if
использует статус выхода команды, которую вы используете вместе с ним.
!
меняет смысл теста таким образом, что
Если pkill compton
завершается успешно, это означает, что был один или несколько compton
процессов, которые сейчас были убиты или, по крайней мере, получили сигнал, и exec compton -b
не будут выполняться.
Если pkill compton
завершится ошибкой, (ни один процесс не соответствует имени, или вpkill
)возникнет какая-то внутренняя ошибка, тело оператора if
вызовет ваш exec compton -b
, что заменит процесс оболочки на процесс, являющийся результатом запуска compton -b
.