I'm tried to parameretrize in a variable the file descriptor number to open a tcp socket using exec command but it failed. Only work correctly when file descriptor number is a constant. In the next example code only success the first retry (RC=0).
Code:
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: $?"
The output is:
Retry 1:
RC: 0
Retry 5:
socket.sh: line 46: exec: 3: not found
RC: 127
or, in other cases:
Retry 1:
RC: 0
Retry X:
socket.sh: line 27: exec: 3: not found
Best Answer
It's easy to understand why it fails when you think of:
You wouldn't want it to behave differently if
$text
happens to contain a number.You'd need to use
eval
here:(you want
$fd
to be expanded in the arguments toeval
, but not$file
).Note that ksh93, zsh and bash have introduced (in April 2005, zsh 4.3.0, bash 4.1-alpha, ksh93r) the possibility to have dynamic fds, like:
Here, the file descriptor (a free one above 10) is chosen by the shell and stored into the
$fd
variable.Which you can use with
... >&$fd
.It matches more closely what you do in other languages:
fd = open(...)
,write(fd, ...)
.