A TCP Port Scanner in Bash
catonmat.net
catonmat.net
function alarm() {
timeout=$1; shift;
bash -c "$@" &
pid=$!
{
sleep $timeout
kill $pid 2> /dev/null
} &
wait $pid 2> /dev/null
return $?
}
alarm 1 "echo >/dev/tcp/google.com/230" && echo "Y" || echo "N"
//this prints 'N' in ~1s
alarm 60 "echo >/dev/tcp/google.com/80" && echo "Y" || echo "N"
//this still returns almost immediately and prints "Y"1. we launch a new bash process to actually run the code (in this case, connect to a host) and store its ID so that we know how to kill it
2. we immediately launch a second process (the block { ... } &), whose only job is to wait for X seconds and then kill the first process
3. then we wait for the first process to end (either because it just finished, or because it was killed before it could) and return its return code.
function alarm() {
timeout=$1; shift; | this just copies the value from the first argument and removes that from the argument list
bash -c "$@" & | here we launch the first process, as in (1) above, passing it all the remaining arguments
pid=$! | .. and store its ID
{ | so, this is the second process
sleep $timeout | we wait the given number of seconds
kill $pid 2> /dev/null | and then we kill the first process, if it still exists
} &
wait $pid 2> /dev/null | 'wait' blocks the execution of the function until the first process terminates, and puts its return value into $?
return $? | this just returns the same that the first process did, so that the caller can know if it was successful or not
}