execコマンドを使用してTCPソケットを開くために変数のファイル記述子番号をパラメータ化しようとしましたが、失敗しました。これは、ファイル記述子番号が定数の場合にのみ機能します。次のコード例では、最初の再試行のみが成功します(RC = 0)。
パスワード:
echo -e "\nRetry 1: "
socket="/dev/tcp/$ip/$port"
exec 3<>$socket
echo "RC: $?"
echo -e "\nRetry 2: "
descriptor=3
socket="/dev/tcp/$ip/$port"
exec $descriptor<>$socket
echo "RC: $?"
echo -e "\nRetry 3: "
descriptor="3"
socket="/dev/tcp/$ip/$port"
exec $descriptor<>$socket
echo "RC: $?"
echo -e "\nRetry 4: "
descriptor=3
socket="/dev/tcp/$ip/$port"
exec "$descriptor"<>$socket
echo "RC: $?"
echo -e "\nRetry 5: "
descriptor=3
socket="/dev/tcp/$ip/$port"
`exec $descriptor<>$socket`
echo "RC: $?"
出力は次のとおりです
Retry 1:
RC: 0
Retry 5:
socket.sh: line 46: exec: 3: not found
RC: 127
または他の場合は次のようになります。
Retry 1:
RC: 0
Retry X:
socket.sh: line 27: exec: 3: not found
答え1
次のことを考えると、なぜ失敗するのかを簡単に知ることができます。
echo $text>some-file
$text
数字が含まれている場合は、別の方法で動作したくありません。
ここで使用する必要がありますeval
:
eval 'exec '"$fd"'> "$file"'
$fd
(引数で拡張を期待しましたが、eval
そうではありません$file
。)
ksh93、zsh、bashでは、(2005年4月、zsh 4.3.0、bash 4.1-alpha、ksh93r)動的fdを持つ可能性を導入しました。たとえば、次のようになります。
exec {fd}> "$file"
ここでは、ファイル記述子(10以上の自由記述子)がシェルによって選択され、変数に$fd
保存されます。
と組み合わせることができます... >&$fd
。
これは、他の言語で実行する操作(fd = open(...)
、)とより一貫性がありますwrite(fd, ...)
。