スペースなしで出力文字列から変数名を区切ります。

スペースなしで出力文字列から変数名を区切ります。

私が望むコードスニペットは次のとおりです。

ループを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使用するには、中かっこを使用して、変数名の始まりと終わりの位置を明確に区別できます。$ip

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ファイルから読み取られた値にアクセスできます。また(指摘したように)touchcommand>>filefileまだ存在しない場合。

ファイルの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失敗し、ループは終了します。

関連情報