これは通常のリダイレクトです。
user@linux:~$ randomcommand
randomcommand: command not found
user@linux:~$
2>
user@linux:~$ randomcommand 2> /dev/null
user@linux:~$
&>
user@linux:~$ randomcommand &> /dev/null
user@linux:~$
ただし、以下のように別のコマンドで同じことを行おうとすると、うまくいきません。
&>
user@linux:~$ > /dev/tcp/127.0.0.1/22 &> /dev/null && echo open || echo closed
bash: connect: Connection refused
bash: /dev/tcp/127.0.0.1/22: Connection refused
closed
user@linux:~$
2>
user@linux:~$ > /dev/tcp/127.0.0.1/22 2> /dev/null && echo open || echo closed
bash: connect: Connection refused
bash: /dev/tcp/127.0.0.1/22: Connection refused
closed
user@linux:~$
これらの構文の何が問題になっていて、どのように修正するのですか?
エラーは、bash
が> /dev/tcp/localhost/22
リダイレクトを処理しているときに出力され、その時点ではstderrはまだリダイレクトされていません。これら2つのリダイレクトの順序を変更するだけです。
if 2> /dev/null > /dev/tcp/127.0.0.1/22; then
echo open
else
echo closed
fi
これらの/dev/tcp/Host/port
は実際のファイルではないことに注意してください。 bash
(またはksh
その機能の由来)は、それらの特殊ファイルにリダイレクトしようとしているという事実を検出します(これを/dev/./tcp
または/dev//tcp
に変更すると、これらのファイルを開く代わりに、TCPソケットを作成し、ホストとポート上でconnect()
を試行します。そして、そのときにconnect
bash
がエラーを報告していることが失敗します。
zsh
には、代わりにztcp
組み込みコマンドが(zsh/net/tcp
モジュール内に)あります。これにより、コマンドが少し直感的になり、サーバー側の接続など多くのことが可能になります。