Telnetを介して状態を自動的に照会しようとしています(この場合は不明です)。アイデアは、何かをgrepし、結果を変数に割り当て、後で条件文に渡すことです。問題は、ターゲットデバイスへのリンクが開始されない可能性があるため、タイムアウトで終了しないと、スクリプトが無期限に中断される可能性があることです。
これは私が期待するものを設定しますoutput
が、リンクのクローズを処理しません。
output=$(telnet 1.2.3.4 1234 | grep "something")
リンククローズを処理すると、予想される出力が出力されます。
timeout --signal=9 3 telnet 1.2.3.4 1234 | grep "something"
出力を含むファイルに出力を送信することもできます。
timeout --signal=9 3 telnet 1.2.3.4 1234 | grep "something" > /tmp/tmpfile.txt
残念ながら、このようなファイルの高速書き込み/読み取りはログファイルをいっぱいにする可能性があるため、オプションではありません。
ただし、すべてを組み合わせようとすると、変数は設定されません。
output=$(timeout --signal=9 3 telnet 1.2.3.4 1234 | grep "something")
または、むしろ空の値に設定します。上記を実行する前に設定すると、後で変数が空になるためです。
答え1
telnet
標準入力にはttyが必要ですが、timeout
それを削除してください。
本当にTelnetの使用に固執する場合は、次のように--foreground
オプションを追加することで実行できますtimeout
。
output=$(timeout --foreground --signal=9 3 telnet 1.2.3.4 1234 2>&1 | grep "something")
また、nc
システムにインストールできる場合は、実際に用途に合わせて使用する必要があります。
output=$(timeout 3 nc 1.2.3.4 1234 | grep "something")
nc
どちらも効果がない場合は、timeout --foreground
ttyを必要としないTelnetに代わるものが必要です。
Bashの独自のネットワーキング機能を使用できるように、質問にタグを追加したことを確認しました。bash
したがって、行は次のようになります。
output=$(timeout 3 cat < /dev/tcp/1.2.3.4/1234 | grep "something")
これがオプションでない場合は、cat
Bashで次のように1行スクリプトに置き換えることができます。
output=$(timeout 3 stdbuf -oL bash -c 'while read line ; do echo "${line}" ; done < /dev/tcp/1.2.3.4/1234 | grep "something"')
少なくともstdbuf
(標準coreutilsパッケージの一部である)システムで利用できることを願っています。
ただし、最後の選択肢ではgrep正規表現に注意してください。一重引用符がある場合は、まずデフォルトの一重引用符ペアを終了してエスケープする必要があります。
これは、シェルから1行スクリプトに変数(ホスト名やポート番号など)を渡す必要がある場合にも必要です。たとえば、
hostname=1.2.3.4
portnumber=1234
output=$(timeout 3 stdbuf -oL bash -c 'while read line ; do echo "${line}" ; done < /dev/tcp/'"${hostname}"'/'"${portnumber}"' | grep "something"')
${hostname}
ここでは、値が信頼できると仮定します${portnumber}
。つまり、あなたまたは他の信頼できる情報源から提供され、違法、無効、または危険な値を提供しません。
答え2
これはリダイレクトされていない標準エラーです(リンクが壊れたとき)!標準エラーを標準出力にリダイレクトするため、問題は解決されます。
output=$(timeout --signal=9 3 telnet 1.2.3.4 1234 2>&1 | grep "something")