Bash-скрипт, который открывает несколько экземпляров netcat и выходит из них
Я пытаюсь создать скрипт, который открывает несколько терминалов gnome и открывает соединение netcat. Через пару секунд я бы хотел закрыть терминалы. Я в растерянности, и я верю, что это невозможно, однако я решил спросить.
Это то, что я имею до сих пор, однако после того, как я запустил его, идентификаторы процесса считаются неправильными, и я полагаю, что это потому, что gnome-терминал разветвляет процесс на bash, а я не собираю этот pid.
ipaddress=$1
port=$2
processarray=()
echo "netcat command set to ip: $ipaddress and port: $port"
if [ -z "$ipaddress" ]; then
echo "No ip address entered"
fi
if [ -z "$port" ]; then
echo "No port entered default set to 0"
$port=0
fi
for i in {0..9}; do
gnome-terminal -e "bash -c \"netcat $ipaddress $port; exec bash\"" & processarray+= ("$!")
done
sleep 10;
for i in "${processarray[@]}"; do
kill "$i"
done
1 ответ
Это потому что gnome-terminal "умный". Когда вы запускаете gnome-terminal, это будет определять, если другой экземпляр gnome-terminal уже бежит.
- Если нет, это создает новый
gnome-terminalобрабатывает и порождает окно. - Если да, это просто приведет к тому, что существующие
gnome-terminalпроцесс порождения нового окна.
Поэтому все gnome-terminal Windows работает как один процесс, с одним PID.
Вы можете легко проверить это, открыв несколько gnome-terminal Windows, а затем получить их PID, выдав xprop _NET_WM_PID где-нибудь и нажмите внутри них. Вы увидите, что PID одинаков для всех окон.
Так что же происходит в вашем сценарии?
Вы захватываете PID gnome-terminal экземпляры запускаются нормально, но проблема в том, что эти PID существуют только в течение доли секунды. Эти процессы вызывают только существующие gnome-terminal процесс, чтобы создать новое окно, а затем завершить.
Так что если у вас уже есть активный gnome-terminal При выполнении вашего сценария (который я предполагаю) PID, которые вы собираете, больше не существуют, когда вы пытаетесь их убить. Если вы этого не сделаете (скажем, вы выполняете этот скрипт из xterm или другой эмулятор терминала), первый полученный вами PID действительно будет "правильным". Следующие идентификаторы PID будут "неправильными". Как только вы войдете в свой цикл убийств, первая итерация убьет все gnome-terminal окна, и следующие будут выводить ошибки, потому что эти PID больше не существует.
Итак, как это решить?
Ну, я могу придумать два пути.
Если вы не настаиваете на использовании
gnome-terminalвместо этого используйте другой эмулятор терминала, который не ведет себя таким образом.xtermнапример, порождает отдельный процесс для каждого окна. Если вы используетеxtermскорее, чемgnome-terminalв вашем сценарии это должно работать. Легко чистить.Если вы настаиваете на использовании
gnome-terminalспособ убить конкретногоgnome-terminalОкно будет убить процесс, который работает внутри этого конкретного окна. Как только вы завершите этот процесс, это окно закроется. Но так как вы используете это-eвариант, этот процесс будетnetcat $ipaddress $portсначала, потом потомbashи трудно получить PID. Вы не можете легко собрать их, как вы делаете с$!, Вы можете попробовать что-то вродеkillall netcatили жеkillall bash, но ясно, что это также прекратит все остальныеnetcatили жеbashслучаи, которые вы, вероятно, не хотите. Вы могли бы возможноgrepболее умно разработанpsпозвоните, чтобы попытаться найти точные PID, которые вы хотите убить, но это шатко и подвержено ошибкам. Честно говоря, я бы просто пошел к решению 1.
Два небольших комментария к вашему сценарию:
Строка 10: должно быть
port=0не$port=0,Строка 13: должно быть
processarray+=("$!")неprocessarray+= ("$!"),
Надеюсь, это поможет.
Редактировать: О, я только что нашел --disable-factory вариант для gnome-terminal, что заставляет его не повторно использовать существующие процессы. Вот ваш фиксированный скрипт:
#!/bin/bash
ipaddress=$1
port=$2
processarray=()
echo "netcat command set to ip: $ipaddress and port: $port"
if [ -z "$ipaddress" ]; then
echo "No ip address entered"
fi
if [ -z "$port" ]; then
echo "No port entered default set to 0"
port=0
fi
for i in {0..9}; do
gnome-terminal --disable-factory -e "bash -c \"netcat $ipaddress $port; exec bash\"" & processarray+=("$!")
done
sleep 10;
for i in "${processarray[@]}"; do
kill "$i"
done