私が望むコードスニペットは次のとおりです。
ループを5回繰り返します。
各反復で次の行を取得する必要があります。その
行をファイルの
先頭に追加します。
ping;いくつかの文を印刷し、ユーザーにコードの進行状況を通知します。
繰り返しが効果がありました。
sed部分をスキップすると、すべてがうまく機能しますが、同じターゲットに対してpingを5回実行します。
host.txt ファイルの各行には、ping する IP アドレスがあります。
for ((i>=1;i<=5;i++))
do
sed -n "$i p" hosts.txt | read output
touch "$output.txt"
date >> "$output.txt"
printf "\nComeçando o teste de $output."
printf "\nTeste em andamento."
ping -c 10 -i 1 "$output" >> "$output.txt"
done
問題は、sed構文に問題があることです。 bashを直接試してみると、sed -n 1p hosts
最初の行が表示されます。しかし、数値が$ iでなければならないので、pの前に$ iを入れると、bashは変数iとそれに引数pを追加する代わりにipを変数として解釈します。
どうすればこの動作を修正し、もはや問題を引き起こすことはできませんか?
答え1
私はあなたがbashを使用していると仮定しているので、これはうまくいきます:
for ((i=1;i<=5;i++))
do
sed -n "$i p" hosts.txt | (
read output
touch "$output.txt"
date >> "$output.txt"
printf "\nComeçando o teste de $output."
printf "\nTeste em andamento."
ping -c 10 -i 1 "$output" >> "$output.txt"
)
done
問題は、bash
ほとんどの外部シェルインタプリタと同様に、ksh
すべてのパイプコンポーネントがサブシェルに配置されるため、output
変数が設定されるとすぐに失われることです。
また、変数が初期化されていないため、未定義 for
の動作が発生したループを修正しました。i
答え2
ご覧のとおり、問題は両方とも有効な変数名であることi
です。したがって、文字の後に続く値をip
使用するには、中かっこを使用して、変数名の始まりと終わりの位置を明確に区別できます。$i
p
sed -n "${i}p" hosts.txt | read output
答え3
少し簡単な解決策は次のとおりです。
for ((i=1; i<=5; i++))
do
read output
date >> "$output.txt"
printf "\nComeçando o teste de %s." "$output"
printf "\nTeste em andamento."
ping -c 10 -i 1 "$output" >> "$output.txt"
done < hosts.txt
< hosts.txt
最後の行の最後にあるを参照してくださいdone
。これにより、その行が一度開き、hosts.txt
その中の最初の5行だけが読み取られます。 don_crisstiが述べたように、ループでこれを行うということは、ファイルを5回sed … hosts.txt | read output
読み取ることを意味します。パイプラインではなくループの残りの部分と平行であるhosts.txt
ため、read output
ループの残りのコードはoutput
ファイルから読み取られた値にアクセスできます。また(指摘したように)touch
。command >> file
file
まだ存在しない場合。
ファイルの1つがhostname.txt
すでに存在する場合、このコードはそのファイルに新しい情報を追加します。古いデータを捨てて最初から始めるには、代わりにdate > "$output.txt"
実行しますdate >> "$output.txt"
。
不明なデータをに直接渡すときは注意してくださいprintf
。まれに「ホスト名」の1つが含まれると、%
コード内でその名前が歪むことがあります。外部データを%s
(印刷文字列)に渡すことをお勧めします。
ファイルの最初の5行だけを読み込んで停止するhosts.txt
のか、それともファイル全体を読みたいのか、偶然その長さが5行なのかは言っていませんでした。ファイル全体を読み取るには:
while read output
do
date >> "$output.txt"
printf "\nComeçando o teste de %s." "$output"
printf "\nTeste em andamento."
ping -c 10 -i 1 "$output" >> "$output.txt"
done < hosts.txt
ファイルの終わりに達すると、文はread output
失敗し、ループは終了します。