호스트가 작동 중인지 확인하는 두 개의 bash 스크립트가 있습니다.
스크립트 1:
#!/bin/bash
for ip in {1..254}; do
ping -c 1 192.168.1.$ip | grep "bytes from" | cut -d" " -f 4 | cut -d ":" -f 1 &
done
스크립트 2:
#!/bin/bash
for ip in {1..254}; do
host=192.168.1.$ip
(ping -c 1 $host > /dev/null
if [ "$?" = 0 ]
then
echo $host
fi) &
done
넓은 범위를 확인할 때 각 ping 명령을 병렬로 처리하고 싶습니다. 그러나 두 번째 스크립트는 리소스 제약으로 인해 실패한 포크 시도를 재시도하지 않는 것 같습니다. 이로 인해 두 번째 스크립트에서는 일관되지 않은 결과가 발생하는 반면 첫 번째 스크립트는 일관된 결과를 제공하지만 둘 다 분기에 실패하는 경우도 있습니다. 누구든지 나에게 이것을 설명해 줄 수 있습니까? 실패한 포크를 다시 시도하는 방법도 있나요?
답변1
원래 포스터의 질문과 관련된 작업에 대해 향상된 코드 조각을 제공하는 답변이 이미 있지만 아직 질문에 더 직접적으로 답변하지 못할 수도 있습니다.
질문은 차이점에 관한 것입니다.
- ㅏ)백그라운드에서 직접 "명령"을 실행하는 것과 비교
- 둘)서브쉘을 백그라운드에 넣습니다(예: 유사한 작업 수행).
2가지 테스트를 통해 이러한 차이점을 확인해 보겠습니다.
# A) Backgrounding a command directly
sleep 2 & ps
산출
[1] 4228
PID TTY TIME CMD
4216 pts/8 00:00:00 sh
4228 pts/8 00:00:00 sleep
하지만
# A) backgrounding a subhell (with similar tas)
( sleep 2; ) & ps
출력은 다음과 유사합니다.
[1] 3252
PID TTY TIME CMD
3216 pts/8 00:00:00 sh
3252 pts/8 00:00:00 sh
3253 pts/8 00:00:00 ps
3254 pts/8 00:00:00 sleep
** 시험 결과:**
이 테스트(만 실행)에서 서브셸 버전은 2개의 하위 프로세스(예: 2개의 / 작업 및 PID) sleep 2
를 사용하므로 명령을 직접 백그라운드로 실행하는 것 이상이 있다는 점에서 차이가 있습니다.fork()
exec
그러나 질문에서 script 1
명령은 단일 명령이 아니라 4개의 명령입니다 sleep 2s
. pipe
다른 경우로 테스트하면
- 씨)4가지 명령을 사용하여 파이프라인을 백그라운드에 배치
# C) Backgrounding a pipe with 4 commands
sleep 2s | sleep 2s | sleep 2s | sleep 2s & ps
이것을 생산한다
[2] 3265
PID TTY TIME CMD
3216 pts/8 00:00:00 bash
3262 pts/8 00:00:00 sleep
3263 pts/8 00:00:00 sleep
3264 pts/8 00:00:00 sleep
3265 pts/8 00:00:00 sleep
3266 pts/8 00:00:00 ps
그리고 script 1
와 s의 관점에서 보면 실제로 더 높은 변형이 될 것임을 보여줍니다.PIDs
fork()
대략적으로 추정하면 스크립트는 약 254 * 4 ~= 1000 PID를 사용하므로 script 2
254 * 2 ~= 500 PID보다 더 많습니다. PID 리소스 고갈로 인해 발생하는 문제는 대부분의 Linux 시스템처럼 거의 발생하지 않습니다.
$ cat /proc/sys/kernel/pid_max
32768
필요한 PID의 32배를 제공하는 경우, 심지어 script 1
관련 프로세스/프로그램(예: sed
등 ping
)이 불안정한 결과로 이어질 가능성은 거의 없어 보입니다.
@derobert 사용자가 언급했듯이 실패의 실제 문제는 scripts
명령 누락이었습니다 wait
. 즉, 루프의 백그라운드에서 명령을 실행한 후 셸과 함께 스크립트의 끝으로 인해 모든 하위 프로세스가 종료되었습니다.
답변2
이렇게 하면 예상한 대로 달성됩니다.
#!/bin/bash
function_ping(){
if ping -c 1 -w 5 $1 &>/dev/null; then
echo "UP: $1"
else
echo "DOWN $1"
fi
}
for ip in {1..254}; do
function_ping 192.168.1.$ip &
done
wait
병렬로 저장하고 실행해 보세요.
도움이 되었나요? 큰 함수로 변환하거나 빠른 while 루프에 사용할 수 있어 프로그래밍에 상상력을 마음껏 발휘할 수 있습니다.
참고: bash를 사용해야 합니다.