If you inspect wait-for-it.sh script. You can see the following function:
wait_for_wrapper()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
else
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
fi
WAITFORIT_PID=$!
trap "kill -INT -$WAITFORIT_PID" INT
wait $WAITFORIT_PID
WAITFORIT_RESULT=$?
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
fi
return $WAITFORIT_RESULT
}
If you look at this line:
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet ...
Now if you run bash wait-for-it.sh google.com:80 this will fail for two reasons:
- The file
wait-for-it.sh will not be recognized if this one is not defined inside the $PATH environment variable.
- The file
wait-for-it.sh has no execution permissions:
Trying to run the wait-for-it.sh script without +x execution permission
Now, if you see the function, this one is passing the value of $0, where $0 is the filename (wait-for-it.sh).
So what timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 does is basically "run itself" (but with some args) using the timeout command:
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT wait-for-it.sh --quiet ...
The solution is using an absolute path or relative path when you run wait-for-it.sh with bash. You also need to assign the execution permissions to that file.
#Using relative path:
bash ./wait-for-it.sh google.com:80
#Using absolute path:
bash /path/to/wait-for-it.sh google.com:80
#e.g.
bash /home/user/wait-for-it.sh google.com:80
Why does "bash wait-for-it.sh google.com:80" fail?
You can edit the function wait_for_wrapper like this:
wait_for_wrapper()
{
echo Running "$0"
echo Whereis "$0": $(whereis "$0")
$0
echo Exit...
exit #to avoid running the following code
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
else
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
fi
WAITFORIT_PID=$!
trap "kill -INT -$WAITFORIT_PID" INT
wait $WAITFORIT_PID
WAITFORIT_RESULT=$?
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
fi
return $WAITFORIT_RESULT
}
If you run bash wait-for-it.sh google.com:80 (with execution perms) you will get this error:
Running wait-for.sh at /home/user/...
Whereis wait-for.sh: wait-for.sh:
wait-for.sh: line 56: wait-for.sh: command not found
Exit...
As I said before, the line $0 is trying to execute wait-for.sh but this one is not in any of directories of the $PATH env variable.
Now I will change the filename wait-for.sh to ls. The ls command will be recognized because my $PATH contains the dir /usr/bin/ which is where ls is usually located. So, if you run:
bash ls google.com:80
You will get:
Running ls at /home/user/...
Whereis ls ls: /usr/bin/ls /usr/share/man/man1p/ls.1p.gz /usr/share/man/man1/ls.1.gz
#This output is of my $HOME directory:
Postman Templates projects
bin go ls
Public Videos Documents
Downloads Pictures temp
Exit...