LINUX.ORG.RU

Почему в Ansible команда «pkill -f nginx || true» возвращает ненуливой код ошибки?

 , , error code, pkill, код возврата


0

1

Столкнулся с очередной загадкой.

Если на целевом хосте в SSH-консоли выполнить команду:

pkill -f nginx || true

То она успешно выполняется, код ошибки, видимый через команду echo $?, всегда нуливой.

Если ту же команду сделать через Ansible:
   - name: "Остановка сервиса Nginx - дополнительный метод"                                                                
     shell: "pkill -f nginx || true"

Тогда эта команда всегда заканчивается ненулевым кодом возврата:
fatal: [siteHost]: FAILED! => {
"changed": true, 
"cmd": "pkill -f nginx || true", 
"delta": "0:00:00.009630", 
"end": "2023-07-01 15:35:48.555054", 
"msg": "non-zero return code", 
"rc": -15, 
"start": "2023-07-01 15:35:48.545424", 
"stderr": "", 
"stderr_lines": [], 
"stdout": "", 
"stdout_lines": []}


Чтобы «съэмулировать» поведение Ansible, я в SSH-консоли удаленного хоста стал выполнять команды:
# bash -c "pkill -f nginx" 
# echo $?
1

# bash -c "exec pkill -f nginx" 
# echo $?
1

# bash -c "pkill -f nginx ; true" 
Terminated
# echo $?
143

# bash -c "pkill -f nginx || true" 
Terminated
# echo $?
143

Похоже, действительно у pkill есть какие-то особенности, которые влияют на код возврата. Но непонятно почему вызов true этот код не подавляет.

В общем, я не пойму как составить команду, которая будет завершаться нуливым кодом возврата в комбинации с pkill.

★★★★★

Ответ на: комментарий от firkax

Строчку Terminated не видишь что ли?

Она только в двух вариантах из четырех. А ненуливой код возврата в четырех случаях из четырех.

Кроме того, что в этой строчке такого? Ну какая-то программа написала в stdout строку «Terminated», имеет на это право. Может и сто строк написать. Как на работу bash и выполнение true появление какого-то сообщения может оказать влияние?

Ну и pkill в таком виде использовать это чушь.

А в каком виде использовать pkill не чушь?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Ну какая-то программа написала в stdout строку «Terminated»,

У тебя везде такой подход? «Ну, кто-то чё-то написал мне в консоль, да и пофиг». Разберись кто её написал и почему, и всё станет ясно. (подсказка: её пишет тот же код, который пишет Segmentation fault при краше)

А в каком виде использовать pkill не чушь?

В интерактивном, набирая руками в консоли. Если надо автоматизировать отправку сигналов процессам, то есть более подходящие способы - pid-файлы, например, или тот же pkill, но более строгими критериями выборки, чем текстовая строка (там есть например ключи -u -s -g и другие, читай man).

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

У тебя везде такой подход? «Ну, кто-то чё-то написал мне в консоль, да и пофиг».

Это у тебя такой подход, потому что ты не знаешь ответа и пишешь общими фразами. Если хотел бы помочь - сам бы выполнил пару команд, а не писал портянки.

Разберись кто её написал и почему, и всё станет ясно.

Мне не станет ясно, а появятся еще вопросы. Например такой, что неясно как отладить однострочную команду в bash.

В интерактивном, набирая руками в консоли.

Ты бухой чтоли? Я тебе показал в топике четыре команды в консоли.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Если хотел бы помочь

Я отредактировал сообщение и подсказку там написал.

Мне не станет ясно, а появятся еще вопросы

Нет, станет. Ну может быть ещё man pkill почитать потребуется чтоб посмотреть что именно она делает, хотя скорее всего это уже не придётся.

Вот ещё такую команду попробуй и подумай почему она делает именно то что делает

bash -c "echo starting ; echo continuing ; pkill -f nginx ; echo finishing ; true"

Ты бухой чтоли? Я тебе показал в топике четыре команды в консоли.

Я про то что ты её в ansible собрался использовать. Ну и при интерактивной работа $? не используют обычно, это для скриптов.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 3)
Ответ на: комментарий от Xintrea

Как на работу bash и выполнение true появление какого-то сообщения может оказать влияние?

Ты сегодня в ударе. Смотри, если я тебе на голову с крыши сброшу кирпич, как это может повлиять на твои действия?

router ★★★★★
()

В общем, всем спасибо, вы мне ничем не помогли.

Я вспомнил старый трюк, который гарантировал удаление всех процессов с заданной подстрокой, за исключением текущего процесса. Нужно просто искомую подстроку оформить как регулярку, чтобы в этой регулярке «визуально явно» не было видно этой подстроки.

pkill -f "[Nn]ginx" || true

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

В общем, всем спасибо, вы мне ничем не помогли.

Знаешь анекдот про менеджера на воздушном шаре?

Так что выспись, включи голову и начни с первого же ответа

router ★★★★★
()
Ответ на: комментарий от router

А не видишь ли ты в них некую закономерность?

Нет.

Тем более, что с подсказки firkax ты уже вспомнил старый трюк

Я намеки не понимаю, уж извини. Пока ты тут с firkax ничего внятного не написали, я все что мне нужно выяснил у Chat GPT.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от keir

Сразу после запуска certbot от Letsencrypt в режиме автоконфигурирования, который из-под себя запускает nginx для первичного обмена сертификатами. Этот certbot срабатывает, но оставляет после себя процессы, которые не снимаются через обычный systemctl stop nginx.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от router

Не хочется влезать в чужие разборки, но все же, в чем разница между

pkill -f nginx || true

bash -c «pkill -f nginx || true»

bash -c же просто запускает ещё один шелл и в нем интерпретирует команду и запускает соответствующие процессы. Или разница может быть в окружении, типа сколько экземпляров nginx запущено?

filosofia
()
Ответ на: комментарий от filosofia

bash -c же просто запускает ещё один шелл и в нем интерпретирует команду и запускает соответствующие процессы.

В первом случае будет закрыт и твой шел

Но у ТС была разница в других командах. В одном случае bash у него успевал обработать завершение дочерних процессов, в другом должен был запустить вторую команду или дождаться ее завршения, не успевал и завершался по сигналу sigterm

router ★★★★★
()
Ответ на: комментарий от filosofia

Хоть напиши чистый pkill, хоть через bash -c, все равно сама команда удалит не только процессы, на которые она нацелена, но и сам процесс, который выполняется, потому что в самой команде присутствует подстрока «nginx».

В случае с ansible, удалялся и процесс, который создает ansible для выполнения этой команды.

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

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Ты имеешь в виду, что pkill -f матчит как по имени команды так и по ее аргументам? Наверное есть опции pkill, чтобы сделать ее поведение строже? Я обычно убиваю процессы по имени killall, он такой фигней не страдает AFAIK.

filosofia
()
Ответ на: комментарий от firkax

для набора руками в консоли есть лучше killall, он сообщает о том что нет такого процесса. А так да грохнуть все процессы по имени, слишком не гуманно это как химическое оружие, лучше высокоточным PID гасить противника )))

s-warus ★★★
()

протестировал во всех вариантах echo $? даёт 0

после
# bash -c «pkill -f nginx ; true»
вариант только один, bash кривой

на простой bash -c «true» какой результат?

s-warus ★★★
()