The following will always kill a node script after a timeout duration is reached.
There are two ways to kill a nodejs/npm script: inside the node script, or inside the shell.
Consider the following script running direct from the command line:
node << EOF const puppeteer = require('puppeteer-extra') const StealthPlugin = require('puppeteer-extra-plugin-stealth'); puppeteer.use(StealthPlugin()); puppeteer.launch( { args: [ '--no-sandbox', '--disable-setuid-sandbox' ], headless: true } ).then(async browser => { const page = await browser.newPage() await page.goto("https://google.com/${username}", { waitUntil : ['load', 'domcontentloaded'] }); let bodyHTML = await page.evaluate(() => document.body.innerHTML); console.log(bodyHTML) await browser.close(); }); EOF
This simple script returns the HTML of google.com to stdout.
However, if the page fails to load, the script will never timeout and your app or container will hang forever.
We can try the following things:
This will put nodejs into a subshell. It will record the process id of node, sleep 5 and then kill it no matter what.
Method 1: precise PID but no output captured
# use this kill switch if you don't care about the node output node file.js & { PID=$!; sleep 5; kill $PID 2> /dev/null; }
However, what if we want to use the output of the nodejs file?
Since we cannot read the variables from the subshell, we need to run the PID script first.
Method 2: closes node by name but you can capture the shell variable!
# use this kill switch if you are capturing the nodejs output in a variable { sleep 5; pgrep node | xargs kill 2> /dev/null ; } & OUTPUT_VAR="$(node file.js)"
Method 2.5: Dynamic nodejs script variables using bash and native shell killswitch
# Use this kill switch if you are capturing the nodejs output in a variable # and use want to use End of Function tags to dynamically change your node script (${username}) { sleep 5; pgrep node | xargs kill 2> /dev/null ; } & OUTPUT_VAR="$(node << EOF const puppeteer = require('puppeteer-extra') const StealthPlugin = require('puppeteer-extra-plugin-stealth'); puppeteer.use(StealthPlugin()); puppeteer.launch( { args: [ '--no-sandbox', '--disable-setuid-sandbox' ], headless: true } ).then(async browser => { const page = await browser.newPage() await page.goto("https://instagram.com/${username}", { waitUntil : ['load', 'domcontentloaded'] }); let bodyHTML = await page.evaluate(() => document.body.innerHTML); console.log(bodyHTML) await browser.close(); }); EOF )"
In any of the above cases, if your script finishes successfully nothing will happen, unless you launch another node within the race condition window!