Как отправить control + c из bash-скрипта? - PullRequest
52 голосов
/ 26 апреля 2011

Я запускаю несколько экранов в скрипте bash, затем запускаю команду django runserver в каждом из них.Я хотел бы также иметь возможность программно останавливать их все, что требует от меня отправки Control+c на runserver.

Как я могу отправить эти нажатия клавиш из моего сценария bash?

Ответы [ 4 ]

67 голосов
/ 26 апреля 2011

Ctrl + C отправляет сигнал SIGINT.

kill -INT <pid> также отправляет сигнал SIGINT:

# Terminates the program (like Ctrl+C)
kill -INT 888
# Force kill
kill -9 888

Предполагается, что 888ID вашего процесса.


Обратите внимание, что kill 888 отправляет сигнал SIGTERM, который немного отличается, но также запрашивает остановку программы.Поэтому, если вы знаете, что делаете (в программе нет привязки к SIGINT), достаточно простого kill.

Чтобы получить PID последней команды, запущенной в вашем скрипте, используйте $!:

# Launch script in background
./my_script.sh &
# Get its PID
PID=$!
# Wait for 2 seconds
sleep 2
# Kill it
kill $PID
12 голосов
/ 26 апреля 2011

CTRL-C обычно отправляет сигнал SIGINT процессу, поэтому вы можете просто сделать:

kill -INT <processID>

из командной строки (или сценария), чтобы повлиять на конкретный processID.

Я говорю «в общем», потому что, как и в большинстве UNIX, это почти бесконечно настраиваемо. Если вы выполните stty -a, вы увидите, какая последовательность клавиш связана с сигналом intr. Вероятно, это будет CTRL-C , но эта последовательность клавиш может быть полностью сопоставлена ​​с чем-то другим.


Следующий скрипт показывает это в действии (хотя с TERM вместо INT, поскольку sleep не реагирует на INT в моем окружении):

#!/usr/bin/env bash

sleep 3600 &
pid=$!
sleep 5

echo ===
echo PID is $pid, before kill:
ps -ef | grep -E "PPID|$pid" | sed 's/^/   /'
echo ===

( kill -TERM $pid ) 2>&1
sleep 5

echo ===
echo PID is $pid, after kill:
ps -ef | grep -E "PPID|$pid" | sed 's/^/   /'
echo ===

Он в основном запускает часовой процесс sleep и захватывает его идентификатор процесса. Затем он выводит соответствующие подробности процесса перед тем, как завершить процесс.

После небольшого ожидания он проверяет таблицу процессов, чтобы узнать, завершился ли процесс. Как видно из вывода скрипта, он действительно исчез:

===
PID is 28380, before kill:
   UID   PID     PPID    TTY     STIME      COMMAND
   pax   28380   24652   tty42   09:26:49   /bin/sleep
===
./qq.sh: line 12: 28380 Terminated              sleep 3600
===
PID is 28380, after kill:
   UID   PID     PPID    TTY     STIME      COMMAND
===
0 голосов
/ 17 апреля 2017
    pgrep -f process_name > any_file_name
    sed -i 's/^/kill /' any_file_name
    chmod 777 any_file_name
    ./any_file_name

например, 'pgrep -f firefox' сгенерирует PID запуска 'firefox' и сохранит этот PID в файл с именем 'any_file_name'. Команда sed добавит kill в начало номера PID в файле any_file_name. Третья строка сделает файл 'any_file_name' исполняемым. Теперь следующая строка уничтожит PID, доступный в файле 'any_file_name'. Запись вышеупомянутых четырех строк в файл и выполнение этого файла может сделать control-C. Работает абсолютно нормально для меня.

0 голосов
/ 17 марта 2017

Вы можете получить PID определенного процесса, такого как MySQL, используя следующие команды: ps -e | pgrep mysql

Эта команда выдаст вам PID MySQL rocess. например, 13954 Теперь введите следующую команду на терминале. убить -9 13954 Это убьет процесс MySQL.

...