Как сценарий Bash может уничтожить версию “сна” себя уже выполнение?

Редактирование Из комментариев ниже я записал запутывающее/вводящее в заблуждение введение, таким образом, я переписываю его.

У меня есть сценарий удара, названный "экранный таймер блокировки", который может быть нажат на рабочем столе. После 30 минут это блокирует экран, и пользователь должен ввести их пароль для разблокирования экрана. Однако, если пользователь передумал, или они хотят сбросить таймер, они должны смочь нажать настольный ярлык снова, и он должен уничтожить previouly рабочее задание, которое спит и считает в обратном порядке.

Я сделал немного метода проб и ошибок до сих пор и поразил контрольно-пропускной пункт.

Отрывок соответствующих норм:

pgrep tv-timer > ~/tv-timer.log
PID=$$ # Current Process ID

Используя cat ~/tv-timer.log:

16382
20711

Один из них равен "$PID" выше, но другой ранее под управлением копия, которую я хочу использовать kill #####.

Каков лучший способ выяснить который <> "$PID" и уничтожение его?

Первый раз, когда скрипт запущен, существует только одна запись, равная "$PID", который я не хочу уничтожать.

Спасибо за помощь!


Предложенный дубликат (Предотвращают дублирующийся скрипт, запущенный в sametime) является проблемой в рамках Родительских и Дочерних процессов. Принятые ответы являются длинными и сложными сценариями обертки вовлечения и/или несколькими строками кода.

Решением, найденным здесь, является одна строка нового кода!

Действительно принятые - выбирают ответ, здесь основан на дублирующейся попытке OP, КОТОРАЯ НЕ РАБОТАЕТ ВОТ!

5
задан 13 April 2017 в 05:24

2 ответа

Проведя много часов после белого кролика в различные альтернативные вселенные, я нашел, что следующее, чтобы быть единственным надежным методом:

# If called a second time, kill the first version already running
kill $(pgrep -f "${0##*/}" | grep -v ^$$)

Если Вы интересуетесь тестированием, это видит Lock Screen Timer код в Спрашивает Ubuntu в: (Приложение, которое заблокирует экран после количества времени набора для Ubuntu),

Производственный фрагмент кода версии (TL; DR)

Подходящий фрагмент кода от lock-screen-timer программа - это:

# Check if lock screen timer already running
pID=$(pgrep -f "${0##*/}") # All PIDs matching lock-screen-timer name
PREVIOUS=$(echo "$pID" | grep -v ^"$$") # Strip out this running copy ($$$)
if [ $PREVIOUS != "" ]; then
    zenity --info --title="Lock screen timer already running" --text="Previous lock screen timer has been terminated."
    kill "$PREVIOUS"
fi

pgrep -f "${0##*/}"

Это находит все случаи того же именованного под управлением идентификатора программы ${0##*/}. Хотя исполняемый файл называют ~/bin/lock-screen-timer настольный ярлык используется для вызова его. Это можно назвать "Экранным Таймером Блокировки" или "Экранным таймером блокировки", или "Напоминают мне о цикле прачечной". Это не может быть трудно кодировано в программу как в исходном вопросе.

Получающийся список идентификатора процесса помещается в переменную $pID

echo "$pID" | grep -v ^"$$"

Это берет содержание $pID (все рабочие случаи lock-screen-timer, или это переименовало настольный короткий путь), и передает список по каналу идентификатора процесса в следующую команду с помощью канала (|) символ.

Следующая команда grep -v удаляет идентификатор процесса то соответствие $$ который является текущим под управлением идентификатором процесса. Морковь (^) говорит grep распознавать целое слово не символьная строка. Например, идентификатор текущего процесса может быть 1518 и предыдущая версия может быть 11518, 21518 или 31518. В этом случае просто соответствуя на 4 цифрах идентификатор процесса делает те 3 соответствия потому что 1518 в 11518. Морковь соответствует на словах так 1518 <> 11518. В процессе идентификатор перечисляет слова, разделяются пробелами (в переменной) или символы новой строки (когда ps -aux команда отображает их на экране).

Результатом этих двух команд является идентификатор процесса предыдущего выполнения lock-screen-timer сценарий. Идентификатор процесса помещается в переменную $PREVIOUS. Если не было предыдущего идентификатора, значение будет "" (пустое поле).

if [ $PREVIOUS != "" ]; then

Это тестирует если $PREVIOUS не равно (!=) пустой указатель / пустое поле "". Очевидно, мы можем только уничтожить ранее под управлением идентификатор процесса, если у нас есть тот!

zenity --info --title="Lock screen timer already running" ...

При выполнении настольного ярлыка Вы не можете echo сообщения пользователю, потому что GUI не отобразит их. Они заканчивают в /var/log/syslog и необходимо отобразить их с cat или gedit, и т.д.

zenity миленькая программа должна отобразить диалоговые окна и формы от удара до GUI (Графический интерфейс пользователя), иначе Рабочий стол. Текст сообщения продолжает, Предыдущий экранный таймер блокировки был завершен.. Это позволяет пользователю запускать новый обратный отсчет таймера или просто отменять. В сущности называя сценарий второй раз и прерывание - то, как можно уничтожить первый сценарий, уже работающий.

kill "$PREVIOUS"

Это просто уничтожает ранее рабочую версию, которую мы хотим сделать, начинаем ли мы новое lock-screen-timer обратный отсчет или нет. Это существенно отличается от исходного вопроса, потому что мы поместили результаты двух загадочных команд в единственную названную переменную $PREVIOUS.

2
ответ дан 23 November 2019 в 09:12

Измените строку:

pgrep tv-timer | grep -v $ > ~/tv-timer2.log

в это:

pgrep tv-timer | grep -v ^$$ > ~/tv-timer2.log

На самом деле, если процессы телевизионного таймера имеет, скажем, PID=26019 и если $$ быть 6019, то grep привел бы к пустой строке, которая не является тем, что Вы хотите.

4
ответ дан 23 November 2019 в 09:12

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

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