#!/usr/bin/env bash echo "Feeling drowsy..."; sleep 10; echo "Woof! Back up after 10 seconds!";
The sleep command in unix allows one to pause execution of a script for a specified duration. It is a very handy tool in times where a script needs to wait for some other asynchronous work to complete. (Kindergarten talks for many!)
What’s the fuss?
In my case, I was working on creating a script that starts a SailsJS server and runs sanity test on the server’s API using Newman. The server had to be started as a daemon so that we could start the server and then execute the command to run the tests. pm2 or foreverjs are good tools to daemonise NodeJS servers.
#!/usr/bin/env bash echo "Starting server..."; pm2 start app.js; echo "Running tests..."; newman -x -y 10 -c test/sanity.json.postman_collection; echo "Stopping server..."; pm2 stop app.js;
The above script might seem to appear just fine, but in reality, no tests get executed. Simple reason — SailsJS servers often take a good 10 seconds to execute all initialisation scripts and be operational. pm2 triggers the server start and immediately goes to execute Newman tests and within that time the server is not yet ready to accept API requests.
Get the script to sleep for a few seconds before executing Newman tests. We already know how to do that. 🙂
Sadly, this is not the simple solution that would truly fix the problem. Culprit being quite a few:
- If your bash scripts has SLEEP command in them, it would not work in a number of Continuous Integration services such as Shippable, Travis-CI, etc. All of these services have some other way to pause execution using configuration options — but that is not a viable option if you intend to have a common script for both local and CI testing. (Good practice.)
It does not work on Windows® Command Prompt (what does?)
pre class=”lang:sh decode:true ” >node -e “n=Date.now;s=n();while(n()-s<5000);”; # 5 seconds delay
node -e "setTimeout(null,5000)"; # 5 seconds delay
I decided to make things neater by publishing this as a module called sleep-ms, which would provide a CLI command to do the same thing as above. Since I was already running the script on systems having Node, adding an additional global module was not a tough job.
npm install sleep-ms -g;
With this, the above code changes and becomes interoperable between local and restricted systems.
#!/usr/bin/env bash echo "Starting server..."; pm2 start app.js; echo "Waiting 5 seconds to complete server boot..."; sleepms 5000; echo "Running tests..."; newman -x -y 10 -c test/sanity.json.postman_collection; echo "Stopping server..."; pm2 stop app.js;