スクリプトで実行されたコマンドを終了するには?

スクリプトで実行されたコマンドを終了するには?

私のスクリプトでtcpdumpを起動し、しばらくしてからもう一度終了したいと思います。 tcpdumpからPIDにアクセスするには? $$を試してみましたが、スクリプトは終了しました。

if [[ $TIMEEND != $Zeit ]];then
                        echo "tcpdump started"
                        sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &
                        pid1=$!
                        break
                        #sudo umount /dev/sdb1
                else
                        sudo kill $pid1
                        echo "autodump stopped"
                fi

これはtcpdumpをgrepしたときの出力なので、pidofとpkillを使うことは不可能だと思います。

ここに画像の説明を入力してください。

私はそれをするためにawkを使ってみました。

  pid1=$(ps -eo pid,args|awk '/abfrage2/ && ! /awk/{print $1}')
                            echo $pid1 >> /tmp/test.txt
                            sudo kill $pid1

pidコマンドを直接使用するとpidが見つかりましたが、killを実行しません。

私のコードについて少し考える必要があるようです。構成ファイルから時刻を取得し、開始時刻が同じであることを確認し、その場合は終了時刻でないことを確認する必要があります。その後、終了時間でない限りtcpdumpを実行する必要があります。終了時間に達したら、tcpdumpを終了する必要があります。私はこれが最善の解決策ではないことを知っていますが、似たようなものと連携させることができれば良いでしょう。

   #!/bin/sh
source /media/usbhd-sdb1/config.conf
pluggedin=true
echo $TIMESTART
echo $TIMEEND
echo $$
echo $Zeit
echo $$ >> /tmp/test.txt
while [ $pluggedin ];do
        Zeit=$(date +"%T")
        if [[ $TIMESTART == $Zeit ]];then
                if [[ $TIMEEND != $Zeit ]];then
                        echo "tcpdump started"
                        sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &
                        #sudo umount /dev/sdb1
                else
                        pid1=$(ps -eo pid,args|awk '/abfrage2/ && ! /awk/{print $1}')
                        echo $pid1 >> /tmp/test.txt
                        sudo kill -9 $pid1
                        echo "autodump stopped"
                fi

        else
        echo "tcpdump not yet started"
        fi
done

答え1

私が理解したら、しばらくtcpdumpを実行して終了したいということです。次のことができます。

#!/bin/bash
sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &
PID=$!
sleep 20
sudo kill -9 $PID
exit 0

$!起動コマンドのpidを提供します。これを終了するには、kill [Signal] [PID]kill tcpdumpコマンドを呼び出すだけです。

tcpdumpを実行していることに注意してください。背景&コマンドの最後に追加します。それ以外の場合は、tcpdumpは引き続き実行されます。展望。これにより、exit 0スクリプトが最後に終了します。

【概念の証拠】

bash -x a.sh
+ PID=21988
+ sleep 10
+ tcpdump -i eth0 -w abfrage2.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
+ kill -9 21988
+ exit 0

[または]

Ericが提案したように、次のようにすることもできます。停止する注文する

#!/bin/bash
timeout 10s tcpdump -i eth0 -w abfrage2.pcap
exit 0

答え2

コマンドはsudo tcpdump行に&記号を追加してバックグラウンドに移動する必要があります。&

sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &

この行はpid1=$!コマンドのPIDをsudo tcpdump変数に入れます。pid1

プロセスを終了するには、以下を使用する必要があります。

sudo kill $pid1

これを使用して、$$現在実行中のプロセスのPIDを示します。

別のスクリプト内でそれを使用しているため、スクリプトを複数回呼び出すことができるため、後続のすべての実行にpid1変数は使用されません。

この変数からPIDを取得するには、次のものを使用できます。

pid1=$(pidof tcpdump)

elseスクリプトセクションで。

または直接使用してください。

sudo pkill tcpdump

tcpdumpコピーを1つだけ実行するとします。

注意すべきもう一つのこと。スクリプトを呼び出すたびにスクリプト$TIMEENDと同じでない場合は、別のプロセスが$Zeit開始されます。tcpdumpより良い解決策は次のとおりです。

if [ "$TIMEEND" != "$Zeit" ] && [ "$(pidof tcpdump)" == "" ]

tcpdumpこれにより、タイミング要件とプロセスの存在をテストします。

答え3

同じスクリプトへの異なる呼び出し間では変数値は保持されません。これは、プログラムPIDを変数に保存することはできず、スクリプトを再実行したときに変数がその値に初期化されると予想できないことを意味します。

一時ファイルにPID値を保存します。

if [...] ; then
    sudo tcpdump -i eth0 ..... &
    disown
    echo $! > somefile.pid
    echo "started"
else
    cat somefile.pid | xargs -n 1 kill
    echo "stopped"
fi

このコマンドはpidsudoではなくPIDを保存するため、再び終了するtcpdump必要はありません。sudo

また、スクリプトを実行するシェルよりもバックグラウンドコマンドが長く持続するようにするには、disown起動後すぐに実行する必要があります。

関連情報