ホストが動作していることを確認する2つの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コマンドを並列に処理したいと思います。しかし、2番目のスクリプトは、リソースの制約のために失敗したフォークの試みを再試行しないようです。これにより、2番目のスクリプトでは一貫性のない結果が発生しますが、最初のスクリプトは一貫した結果を提供しますが、どちらもブランチに失敗することがあります。誰でも私にこれを説明できますか?失敗したフォークを再試行する方法もありますか?
答え1
もともとポスターの質問に関連するタスクに改善されたコードスニペットを提供する答えはすでにありますが、まだ質問に直接答えることができない可能性があります。
質問は違いについてです。
- ㅏ)バックグラウンドで直接「コマンド」を実行するのと比較
- 2)サブシェルをバックグラウンドに配置します(たとえば、同様の操作を実行します)。
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を使用する必要があります。