Issue
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?"
Solution
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)
Answered By - Daniel Widdis Answer Checked By - Katrina (WPSolving Volunteer)