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