스크립트에서 실행된 명령을 종료하는 방법은 무엇입니까?

스크립트에서 실행된 명령을 종료하는 방법은 무엇입니까?

내 스크립트에서 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 복사본을 하나만 실행한다고 가정합니다.

주의해야 할 또 다른 사항. 스크립트를 호출할 때마다 스크립트 $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

이 명령은 pid sudo가 아닌 PID를 저장하므로 다시 종료할 tcpdump필요가 없습니다.sudo

또한 스크립트를 실행하는 쉘보다 백그라운드 명령이 더 오래 지속되도록 하려면 disown시작 후 즉시 실행 해야 합니다.

관련 정보