네트워크 연결을 끊을 때 스크립트 종료

네트워크 연결을 끊을 때 스크립트 종료

저는 Raspberry Pi를 사용하여 eth0을 통해 센서의 데이터를 기록하려고 합니다. 내 코드(및 약 100가지 변형의 sigterms, kills,exit 등)를 실행하면 컬렉션을 분리한 후에도 컬렉션이 사라지지 않고 내 파일이 새로 고쳐지지 않습니다. 다음은 내 코드의 (대부분) 현재 반복입니다.

blink은 제가 제외했던 함수이지만 프로그래밍 방식으로 작동하고 상호작용할 수 없습니다.

연결이 끊어진 네트워크 케이블을 파일을 플러시하고 스크립트를 종료하는 신호로 성공적으로 사용하는 방법을 아는 사람이 있습니까?

#!/bin/bash

# Function to check if the Ethernet interface is active
eth_active() {
    if ip link show eth0 up >/dev/null 2>&1; then
        return 0
    else
        return 1
    fi
}


dt=$(date '+%Y_%m_%d_%H_%M')
umask 0111
touch $dt.pcap

sleep 5

# Main script
if eth_active; then
# Ethernet active, execute the command
    dumpcap -i eth0 -P -w $dt.pcap &
    pid=$!
    if eth_active; then
        echo "working"
        sleep 2
    else
        kill -9 $pid
        echo "Ethernet interface is severed. Exiting..."
        blink
        shutdown -h now
    fi
else
# Ethernet interface is severed, exit the script
    echo "Not getting data"
    blink
    exit 0
fi

답변1

파일을 플러시하고 스크립트를 종료하기 위한 신호로 연결 해제를 성공적으로 사용할 수 있는 방법을 아는 사람이 있습니까?

첫째, 이 기능은 eth_active인터페이스 링크가 연결되어 있는지 여부를 올바르게 식별하지 못합니다. 간단한 코드를 실행하여 이를 테스트할 수 있습니다.

iface=enxb827eb315364    # Interface name
while sleep 3; do date; ip link show "$iface" up; echo SS=$?; echo; done

종료 상태는 다음과 같이 표시됩니다 SS=…. 이더넷 연결에 관계없이 항상 0("ok")을 반환하는 것을 볼 수 있습니다.

Tue 10 Oct 09:52:41 BST 2023
2: enxb827eb315364: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether b8:27:eb:31:53:64 brd ff:ff:ff:ff:ff:ff
SS=0

Tue 10 Oct 09:52:44 BST 2023
2: enxb827eb315364: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000
    link/ether b8:27:eb:31:53:64 brd ff:ff:ff:ff:ff:ff
SS=0

[…]

Tue 10 Oct 09:52:53 BST 2023
2: enxb827eb315364: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether b8:27:eb:31:53:64 brd ff:ff:ff:ff:ff:ff
SS=0

이제 이 문제를 해결해 보겠습니다.

# Check if the Ethernet interface is active.
# Usage: eth_active [<interface_name>]
# Omitting the <interface_name> will default to eth0
#
eth_active() {
    ip link show "${1:-eth0}" up 2>&1 | grep -qF "state UP"
}

함수의 반환 값은 상태(0 = 텍스트 일치 성공)에서 파생될 수 있으므로 명시적인 값을 반환 grep할 필요가 없습니다 .if … then

다음으로 이를 확인하려면 루프가 필요합니다. 그렇지 않으면 프로그램이 단순히 위에서 아래로 실행되고 dumpcap하위 프로세스로 시작된 다음 종료됩니다.

문제 설명에 구현하려는 논리를 이해할 수 없으므로 루프 작성 방법을 설명하기 위해 여기에서 단순화했습니다. 이는 코드를 대체하기 위한 것이 아니라 직접 작성하는 방법을 이해하는 데 도움을 주기 위한 것입니다.

# Set the interface name
iface=eth0

# Start the packet capture
dumpcap -i "$iface" -P -w "$(date +'%Y-%m-%d_%H%M').pcap" &
pid=$!  

# Do nothing until either the network cable is pulled or dumpcap dies
while eth_active "$iface" && kill -0 "$pid" 2>/dev/null
do
    sleep 3
done

# Kill dumpcap if it's still around
kill "$pid" 2>/dev/null && ( sleep 3; kill -KILL "$pid" 2>/dev/null ) &

kill -9처음에는 ( )를 사용하지 않고 SIGKILL기본값인 SIGTERM. SIGKILL이는 대상 프로세스가 정리할 기회를 허용하지 않기 때문에 일반적으로 나쁜 선택입니다. 프로세스를 종료하는 일반적인 방법이 아니라 실수로 간주됩니다. 이 dumpcap경우 SIGTERM종료하라고 지시합니다. 더 중요한 것은 미해결 출력을 캡처 파일로 플러시한다는 것입니다. 하지만 비틀림을 방지하기 위해 3초 정도 기다린 후 큰 망치로 두드립니다. 그것이 사라지면 오류가 발생 kill하지만 여기서는 문제가 되지 않습니다.

답변2

다음과 같이 시도해 볼 수 있습니다(테스트되지 않음).

if eth_active; then
    # Ethernet active, execute the command
    dumpcap -i eth0 -P -w "$dt.pcap" &
    pid=$!

else
    # Ethernet interface is severed, exit the script
    echo "Not getting data"
    blink
    exit 0
fi

## run until eth_active is false
while eth_active; do
    echo "working"
    sleep 2
done

## Only kill the PID if the $pid variable is not empty
[ -n "$pid" ] && kill -9 "$pid"

echo "Ethernet interface is severed. Exiting..."
blink
shutdown -h now

인터페이스가 작동하는지 테스트하고, 그렇다면 명령을 시작한 다음 2초마다 인터페이스를 다시 테스트하고 나머지 스크립트를 계속 진행합니다. 인터페이스가 작동 중지된 경우 머신을 종료합니다.

그러나 나는 당신이 원하는 논리를 잘 이해하지 못합니다. 이 스크립트를 실행할 때 인터페이스가 작동하지 않으면 단순히 시스템이 종료됩니다. 이것이 원하는 것입니까?


중요한: 바라보다크리스 데이비스의 답변eth_active()이는 귀하의 작업이 예상대로 작동하지 않는다는 신호입니다 .

관련 정보