我尝试在变量中参数化文件描述符编号以使用 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 以上的空闲描述符)由 shell 选择并存储到$fd
变量中。
您可以将其与... >&$fd
.
它更符合您在其他语言中所做的操作:fd = open(...)
, write(fd, ...)
。