Home > Software design >  execSync throws and error trying to run node
execSync throws and error trying to run node

Time:11-09

I am running some processes inside of an EC2 instance.

To run it I initiate it with an SSM command:

cd / && cd home/ec2-user && . .nvm/nvm.sh && cd ufo && npm run start

and inside of it, I have a method in app.ts which is initialized with ts-node app.ts

import { execSync } from 'node:child_process';
import { takeNextScheduledAudit } from './sqs-scheduler';
import { uploadResultsToBucket } from './s3-uploader';
import { AuditRunParams } from "./types";
import { sendAuditResults } from "./sendResults";

(async function conductor(): Promise<void> {
    const nextAuditRunParams = await takeNextScheduledAudit();
    if (!nextAuditRunParams) {
        execSync("sudo shutdown -h now");
    }

    const { targetUrl, requesterId, endpoint } = nextAuditRunParams as AuditRunParams;
    try {
        execSync(`npx user-flow --url=${targetUrl} --open=false`);
        const resultsUrl = await uploadResultsToBucket(targetUrl);
        await sendAuditResults(requesterId, endpoint, resultsUrl);
    } catch (error) {
        console.log(error);
    }
    await conductor();
})();

If I log in manually and run npm run start the scripts works as intended but if I run it using the SSM command I get this output:

> start
> ts-node app.ts
Error: Command failed: npx user-flow --url=https://deep-blue.io/ --open=false
at checkExecSyncError (node:child_process:841:11)
at execSync (node:child_process:912:15)
at conductor (/home/ec2-user/ufo/app.ts:15:17)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
status: 243,
signal: null,
output: [ null, <Buffer >, <Buffer 0a> ],
pid: 2691,
stdout: <Buffer >,
stderr: <Buffer 0a>
}

and this error:

Error: Command failed: sudo shutdown -h now
at checkExecSyncError (node:child_process:841:11)
at execSync (node:child_process:912:15)
at conductor (/home/ec2-user/ufo/app.ts:10:17)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async conductor (/home/ec2-user/ufo/app.ts:21:5) {
status: null,
signal: 'SIGTERM',
output: [ null, Buffer(0) [Uint8Array] [], Buffer(0) [Uint8Array] [] ],
pid: 2705,
stdout: Buffer(0) [Uint8Array] [],
stderr: Buffer(0) [Uint8Array] []
}
failed to run commands: exit status 1

Moreover, if I run execSync("node -v && npx -v") it also throws an error.

Why can I run this script when i am logged in but if i run it via a SSM command it does not recognize node inside of node?

--- Edit - Added Info ---

When running execSync(node -v && npx -v,{shell: '/bin/bash'}) I get an error:

Error: Command failed: node -v && npx -v

When running execSync(ps -p $$ && echo $SHELL, {shell: '/bin/bash'}):

PID TTY TIME CMD
7817 ? 00:00:00 bash
/bin/bash

And when I loggin and do ps -p $$ && echo $SHELL I get:

  PID TTY          TIME CMD
 6873 pts/0    00:00:00 bash
/bin/bash

CodePudding user response:

By default, all of the child_process functions execute in the same environment as the process that launched them. I don't have an account handy to test with, but it's quite likely that SSM skips over a traditional shell and just executes certain runtimes directly.

You can use the exec options like this to set a particular shell in which to launch the process:

const output = execSync('echo "doing stuff"', {
  shell: '/bin/bash',
})
console.log('***** output:', output.toString())

This is assuming the OS you're using for the EC2 instance has bash available. Most flavors of linux should, but for what you're doing there, /bin/sh is sufficient if not. To get a list of the available shells, you can run:

cat /etc/shells

## or possibly
sudo cat /etc/shells

EDIT: Since you say it works fine in a shell already, you have presumably already handled this, but user-flow would also have to be available. It's not a module from npmjs, so would need to already be present on the box as either a local dependency or a private repo to which the EC2 instance has access.

  • Related