Почему мои операторы оболочки вызывают блокировку? bash -c "ps ax | grep 'tcpdump' | grep -v grep | kill -9 $(awk '{print $1}')"

Я переписываю функцию для альтернативы os.system() в Python, чтобы гарантировать, что вывод процесса регистрируется.

    def log_system(self, cmd: str):
        cmd = cmd.rstrip(' ')
        if cmd[-1] == '&' and cmd[-2] != '&':
            cmd = cmd[:-1]
            # Redirects standard error to standard output for logging
            executing = os.popen('bash -c ' + '"' + cmd + '"' + '>/dev/stdout 2>&1 &')
        else:
            executing = os.popen('bash -c ' + '"' + cmd + '"' + '>/dev/stdout 2>&1')
        res = executing.readlines()
        ret = executing.close()
        if len(res) > 0:  # print message if have some content
            msg = ''.join(res)
            if ret is None:  # None means process return successfully
                log.i(msg)  # print stdout
            else:
                log.e(f'cmd execute failed: {cmd}\n' + msg)  # print stderr

Исходное утверждение работает хорошо, и это:

os.system("ps ax | grep 'tcpdump' | grep -v grep | kill `awk '{print $1}'` ")

После того, как я использую log_system(), сценарий оболочки может быть:

bash -c "ps ax | grep 'tcpdump' | grep -v grep | kill `awk '{print $1}'`"

Но когда я выполняю код, он блокируется, я не знаю, что произошло.

Я использую терминал для повторной попытки, этот скрипт не блокирует:

ps ax | grep 'tcpdump' | grep -v grep | kill `awk '{print $1}'`

и это тоже блокирует:

bash -c "ps ax | grep 'tcpdump' | grep -v grep | kill -9 $(awk '{print $1}')"
bash -c "ps ax | grep 'tcpdump' | grep -v grep | kill `awk '{print $1}'`"
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Команда kill не принимает идентификаторы процессов на стандартный ввод, их необходимо указывать в качестве аргумента.

В частности, ваш текущий фрагмент команды (независимо от того, что входит в стандартный ввод kill) будет зависать навсегда, потому что awk ожидает своего стандартного ввода (терминала), по сути:

kill `awk '{print $1}'`

Следовательно, команда должна быть примерно такой:

kill $(ps ax | grep 'tcpdump' | grep -v grep | awk '{print $1}')

с $() захватом стандартного вывода своего содержимого и использованием его в качестве аргумента командной строки для kill.


Тем не менее, вы также можете посмотреть один из моих предыдущих ответов. Есть лучшие инструменты для поиска и/или уничтожения процессов, такие как pgrep и pkill. Если они у вас есть, они, как правило, лучше, чем попытки сделать это с помощью ps/grep/awk пайплайнов.

Спасибо! Я пробую этот код ниже, и он работает хорошо. shell bash -c "kill $(ps ax | grep '[t]cpdump' |awk '{print $1}')" Тем не менее, я все еще хочу знать, в чем разница между следующими двумя фрагментами: ```shell ps ax | grep '[t]cpdump' | kill awk '{print $1}' # неблокирующий bash -c "ps ax | grep '[t]cpdump' | kill awk '{print $1}'" # блокирующий

Zheng Li 13.02.2023 07:21

Это зависит от оболочки. Если вы запустите cmd1 | cmd2 $(cmd3) в bash или dash, и cmd2, и cmd3 будут читаться из конвейера. Но в zsh только cmd2 читает из канала (cmd3 по сути находится за пределами конвейера и читает из терминала или чего-то еще). Однако предложенная здесь замена должна работать в любой оболочке семейства sh.

Gordon Davisson 13.02.2023 07:23

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