0

I am trying to get a cloud server (built from an image I have saved) to execute a script from a URL upon startup, but the script is not executing properly.

I used one of the answers from Execute bash script from URL to configure a curl script, and am executing that script via the @reboot directive in crontab (Ubuntu 14.04). My setup looks like this:

The script contains these commands:

user@cloud-server-01:~$ cat startup.sh
#! /bin/sh
/usr/bin/curl -s http://192.168.100.59/user/startup.sh.txt | bash /dev/stdin

I call the script via crontab:

user@cloud-server-01:~$ crontab -l
@reboot /home/user/startup.sh > startup.log 2>&1 &

If I manually execute the script from the command line using exactly the same command, it works fine. However, executing by crontab on startup, it seems to hang, and I see the following processes running:

user@cloud-server-01:~$ ps ux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
user      1287  0.0  0.1   4444   632 ?        S    19:17   0:00 /bin/sh /home/user/startup.sh
user      1290  0.0  0.7  89536  3536 ?        S    19:17   0:00 /usr/bin/curl -s http://192.168.100.59/user/startup.sh.txt
user      1291  0.0  0.2  12632  1196 ?        S    19:17   0:00 bash /dev/stdin

Am I missing something obvious in why the cron execution isn't giving me the same results as my command line?

EDIT:

Thanks Olof for the redirect on my troubleshooting. In fact, curl is executing, and if I wait long enough (several minutes) it appears to operate as desired. I suspect the problem is that the network interface and/or URL is not available when curl is initially called, and while it may poll for a connection, it probably backs off its polling interval. So the question now becomes, "How do I check whether I have a connection to this URL before calling curl?"

2 Answers 2

1

This is not a bash problem; your curl command is still running so bash is still running, waiting for curl to close the pipe that the bash shell is reading from.

To troubleshoot your curl invocation I would run it first without piping to bash to check that I get the output I expected.

Sign up to request clarification or add additional context in comments.

5 Comments

something like bash <(/usr/bin/curl -s http://192.168.100.59/user/startup.sh.txt) ???
@Jord, that is equivalent to the invocation in the question with a different (modern-shell-only) syntax. The OP was using /bin/sh to invoke curl and that may not be able to handle that syntax.
@Olof, thanks for the hint on where to look. I've got it working by throwing a 60-second sleep into the script to give the network a chance to get setup. Still looking for a better way to poll for network connectivity within my own script.
My pleaseure, @DanielWiddis. Checking that something reponds is a sound idea. I would not bother with the check_online setting global variables and printing strings. Somthing like: while ! nc -z $HOST 80 > /dev/null 2>&1; do sleep 5; done would suffice, IMHO.
Sweet. I'll try that. I am not very familiar with bash syntax so I steal liberally from elsewhere on the internet!
0

The hint in Olof's answer got me there, but I'm posting the full result here for completeness:

Because of a cloud provider's script which takes 20-40 seconds following reboot, my desired connection IP wasn't available to me when I first executed cron. It would either timeout, or connect after a significant delay. I have modified my connection script to poll the connection until it is available before calling curl:

#! /bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOST_IP=192.168.100.59

check_online() {
    IS_ONLINE=$(netcat -z -w 5 $HOST_IP 80 && echo 1 || echo 0)
}

# Initial check to see if we're online
check_online

# Loop while we're not online.
while [ $IS_ONLINE -eq 0 ];do
    # We're offline. Sleep for a bit, then check again
    sleep 5;
    check_online
done

# Run remote script
bash <(curl -s http://${HOST_IP}/user/startup.sh.txt)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.