Почему я не могу получить вывод pgrep прямо для переменной в сценарии bash?

Файловые дескрипторы принадлежат процессу: то есть текущему процессу. Сразу после выхода из процесса назначения не действуют. Даже подоболочка (или любой дочерний процесс), наследующая файловые дескрипторы, из fork () вызывает свои собственные копии файловых дескрипторов (файловый дескриптор - это просто число, указывающее на ресурс ввода-вывода в ядре Linux). Это похоже на открытые файлы - открытие файла в одном процессе не делает его открытым для всех, и если вы не закроете его самостоятельно, Linux закроет его и очистит, когда процесс завершится.

4
20.03.2019, 01:19
2 ответа

Вы должны контролировать статус завершения процесса 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
6
27.01.2020, 20:46

Вы получаете вывод 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.

8
27.01.2020, 20:46

Теги

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