Few questions about this script

Joined
Apr 16, 2023
Messages
172
Reaction score
20
Credits
1,677
Bash:
host=www.google.com
port=443
while true; do
    current_time=$(date +%H:%M:%S)
    r=$(bash -c 'exec 3<> /dev/tcp/'$host'/'$port';echo $?' 2>/dev/null)
    if [ "$r" = "0" ]; then
        echo "[$current_time] $host $port is open"
    else
        echo "[$current_time] $host $port is closed"
        exit 1 # To force fail result in ShellScript
    fi
    sleep 60
done
I saw this script in order to continuously poll connections to port 443 on www.example.com and log the output. But I am not understanding how the value of r is calculated?

Let's decode
Code:
3<> /dev/tcp/'$host'/'$port'

Code:
echo $?

What I am thinking is that echo $? will always return exit status success=0. Regardless of success or failure of the previous command. That means the return value of this command will always be 0 and host port will always be open(I've tested and I know my concept is wrong here).

Any guidance to understand this please.
 


The exitcode is the exitcode of the MAIN command of your call.
In this case it's calling "bash", which does whatever you ask it to do, but the exitcode will be whether or not bash was able to run, or not. Suppose you spelled "bash" incorrectly, your exitcode won't be zero anymore.
All commands, and programs, should return an exitcode, but if you get the exitcode of a complex command, only one part of that "command" will be the one that determines the general exit code.

I'm not entirely sure my explanation makes sense, I'm sure it can be explained better but in the best case you'll get the direction this is going.
 
The variable r is effectively assigned the value of whatever is output by the echo $? after the exec command.

The exec command is attempting to assign file descriptor 3 to /dev/tcp/$host/$port.
The echo $? echoes the result of that operation.

In other words, if the exec command manages to assign the file descriptor to the port - the port is open. If it fails to assign, then the port is closed.

The echo $? command echoes the exit status of the exec command to the stdout of the bash subshell it’s running inside.

So after the Bash sub-process has executed the commands and exits, its stdout buffer will either contain "0" (success - port is open) or "1" (failure - port is closed).
Whatever was in the bash sub-process’s stdout buffer is assigned to the variable r.

Also, in the sub-shell:
Error messages are being redirected to /dev/null. This ensures that in the event of execs failure to assign the file descriptor - the stdout of the sub-shell won’t end up being polluted by any error messages. Thus ensuring that the stdout will only contain the exit code of the exec command.

I hope that all makes sense!!
 
Last edited:
Well, it's pretty easy to debug exitcodes
Purposely cause failure, and see if the exitcode changes. If not, you're watching the exitcode of the wrong command. Can't be a programmer and never have this issue :)
 

Members online


Top