Сценарий Bash, который открывает несколько netcat экземпляров и выходит из них

Я пытаюсь создать сценарий, который открывает несколько терминалов гнома и открывает netcat соединение. После пары секунд я хотел бы, чтобы терминалы закрылись. Я в замешательстве, и я полагаю, что это не может быть сделано, однако я полагал, что спрошу.

Это - то, что я имею до сих пор, однако после того, как я выполняю его, идентификатор процесса считают неправильным, и я полагаю, что это - потому что терминальные гномом ветвления процесс для избиения и я не получаю тот 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
2
задан 6 September 2014 в 02:26

1 ответ

Поэтому gnome-terminal "умно". Когда Вы разжигаете gnome-terminal, это определит если другой экземпляр gnome-terminal уже работает.

  • Если не, это создает новое gnome-terminal обработайте и порождает окно.
  • Если да, это просто вызовет это существующее gnome-terminal обработайте для порождения нового окна.

Поэтому все gnome-terminal Windows, запущенные как единственный процесс, с единственным PID.

Можно легко проверить это путем открытия нескольких gnome-terminal окна, затем получите их PIDs путем издания xprop _NET_WM_PID где-нибудь и щелчок в них. Вы будете видеть, что PID является тем же для всех окон.

Таким образом, что происходит в Вашем сценарии?

Вы получаете PIDs gnome-terminal экземпляры, которые Вы запускаете хорошо, но проблема, те PIDs, существуют только для части секунды. Эти процессы только вызывают существующее gnome-terminal обработайте, чтобы породить новое окно, затем завершиться.

Таким образом, если у Вас уже есть активное gnome-terminal обработайте при выполнении сценария (который я принимаю), PIDs, которые Вы собираете, не существуют больше, когда Вы пытаетесь уничтожить их. Если Вы не делаете (скажите, Вы выполняете тот сценарий от xterm или некоторый другой эмулятор терминала), первый PID, который Вы собираете, действительно будет "корректен". Следующий PIDs, который Вы собираете, будет "неправильным". После того как Вы вводите свой цикл уничтожения, первое повторение уничтожило бы все gnome-terminal окна и следующие произвели бы ошибки, потому что те PIDs больше не существуют.

Так, как решить это?

Ну, от летучей мыши я могу думать о двух путях.

  1. Если Вы не настаиваете на том, чтобы использовать gnome-terminal, используйте некоторый другой эмулятор терминала вместо этого, который не ведет себя таким образом. xterm например, порождает отдельный процесс для каждого окна. Если Вы используете xterm вместо gnome-terminal в Вашем сценарии это должно работать. Легкий и чистый.

  2. Если Вы действительно настаиваете на том, чтобы использовать gnome-terminal, способ уничтожить определенное gnome-terminal окно должно было бы уничтожить процесс, который это выполняет в том определенном окне. Как только Вы завершаете тот процесс, то окно закроется. Но так как Вы используете это -e опция, этот процесс будет netcat $ipaddress $port во-первых, затем впоследствии bash, и трудно получить PIDs. Вы не можете легко собрать их, как Вы в настоящее время делаете с $!. Вы могли попробовать что-то как killall netcat или killall bash, но ясно который также завершит все другой netcat или bash экземпляры, которые Вы, вероятно, не хотите. Вы могли возможно grep по некоторым умно разработанным ps звоните, чтобы попытаться найти точный PIDs, который Вы хотите уничтожить, но это шатко и подвержено ошибкам. Честно, я просто пошел бы для решения 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

1
ответ дан 7 October 2019 в 03:59

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

Похожие вопросы: