I've a package.json on which I define a debug script. This script launches a node app.
The whole npm script is being launched by a test, and this last one must kill the debug script once the test ends.
So when I spawn npm run debug and I kill it, the node process isn't killed.
I've tried to either kill the whole process with child_process.kill and spawning a kill bash command with no luck since the pid doesn't belong to the node launched using npm run debug.
How to kill that node process for which I don't own its pid?
You don't have to necessarily own the PID to be able to kill it (as long as the user running the scripts has permission to do it).
You could spawn commands and do it like you would in command-line (of which there are a number of ways). There are also packages like find-process which you can use to find the process that way as well.
An even easier way is to write some file that has the pid in it when debug starts up (if you can). Then you can just read that file back in to get the PID.
// in debug
import { writeFile } from 'fs';
writeFile('debug.pid', process.pid, 'utf8', err => err && console.log('Error writing pid file'));
// in app where it'll kill
import { readFile } from 'fs';
let debugPid;
readFile('debug.pid', 'utf8', (err, data) => err ? console.log('Error reading pid file') : debugPid = data);
Regardless of approach, once you have the PID, use process.kill() to kill it:
process.kill(pid);
Related
I was trying to use "spawn" from "child_process" to talk to the "ssh" utility (Ubuntu 20, bash 5.0, node 19.6), but got the message "Pseudo-terminal will not be allocated because stdin is not a terminal" (using "-t -t" made it bypass stdout and print directly to the terminal).
In this case I can probably just use a dedicated module, but I doubt that it is the only program that is fussy about where its input is coming from and I'd like to avoid this issue in the future.
per ssh man page, you should use -T (disables pseudo-tty allocation) instead of -t (forces pseudo-tty allocation).
this code spawns a new child process running the ssh command with the provided username and hostname, then listens to stdout and stderr streams:
const { spawn } = require('child_process');
// define the SSH command to execute and its arguments
const ssh = spawn('ssh', ['-T', 'user#host']);
// handle SSH output events
ssh.stdout.on('data', (data) => console.log(`stdout: ${data}`));
ssh.stderr.on('data', (data) => console.error(`stderr: ${data}`));
ssh.on('close', (code) => console.log(`child process exited with code ${code}`));
to interact with the SSH server, you can write to the stdin stream of the child process, for example, sending a ls command:
ssh.stdin.write('ls\n');
to close the session you can either:
close the input stream to signal the end of input
ssh.stdin.end();
send an exit command
ssh.stdin.write('exit\n');
remember to replace the user#host accordingly, handle errors and exceptions appropriately.
I want to build a nodejs application which will do some automatic work for me . But I want to know if I can execute terminal commands in nodejs . Is there any module which will be helpful to access command line interface ? Suppose I want to run this command code . or ifconfig or cd. So how can I do this from nodejs application ?
I know I can run nodejs from my terminal But I want to access terminal and do whatever I want .like installing other softwares from terminal Like executing 'apt install package-name'
So what you want is a portable method of running system specific functionality. Thankfully, nodejs has a module to do this called the child_process module. For more specific information you can glance at the linked documentation, but a basic example goes like this:
const { spawn } = require('child_process');
// Here we make the call making sure to list the command first and the arguments as the next parameter in a list
const diff = spawn('diff', ["texta.txt", "textb.txt"])
// We can also log the output of this function with
diff.stdout.on('data', (data) => {
console.log(data.toString());
});
// or we can log the exit code with
diff.on('exit', (code) => {
console.log(`Child exited with code ${code}`);
});
My discord bot currently has a local recording feature that creates a file every time someone speaks. When the bot disconnects from the voice call (from !stoprecording), I need to manually run node merge.js in my terminal to merge all those files into 1 main PCM file. From there, I need to run another FFMPEG terminal command to convert the merged PCM file into an MP3. That's fine on it's own, but is was curious if there was any way I could automate that? Is there a way to execute terminal commands in the actual code itself. So that every time !stoprecording is ran, it would merge the file and convert to mp3 using FFMPEG?
You can use Node.JS native stuff to exec shell command when handling discord.js bot command
const util = require('util');
const exec = util.promisify(require('child_process').exec);
async function ls() {
const { stdout, stderr } = await exec('ls');
console.log('stdout:', stdout);
console.log('stderr:', stderr);
}
// ls function is called in command exec function
ls();
We have recently upgraded from Node 0.12.2 to 8.10.0 on our test server. We are now getting -4048 EPERM when we try to export a Json file. So we went back to the previous version of Node and we are getting the same error! We can write files to that directory from windows and also have created a small node js file to write files to the remote server and it works. We have tried completely removing node and reinstalling (including several server reboots and got nowhere). We initially tried npm cache clear (--force) in both powershell and cmd at admin level after reading several posts and this did not work. The test server is not open so we cannot run npm install for example against package.json. Has anyone had a similar problem?
var fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
The account the node service was running on was the wrong one and didn't have permissions for the remote server - simple as.
When I run docker pull my-image from my terminal this is how my output looks like.
59e69571f6c7: Pull complete
43da27f69c98: Pull complete
d22174e9eddd: Pull complete
cc0ac48a6d21: Downloading 312.3 MB/2.888 GB
b47aa969d5dc: Download complete
When I run a piece of Node.js code
const { exec } = require('child_process');
exec('docker pull my-image', (error, stdout, stderr) => {
if (error) {
console.error('exec error: ${error}');
return;
}
console.log('stdout: ${stdout}');
console.log('stderr: ${stderr}');
});
My output looks like this.
c49bda5ed612: Waiting
43da27f69c98: Verifying Checksum
43da27f69c98: Download complete
d22174e9eddd: Verifying Checksum
d22174e9eddd: Download complete
b47aa969d5dc: Verifying Checksum
I was expecting same output. Mainly the information regarding how much is downloaded and remaining. If I want to progress a progress bar based on the size of the image downloaded, there is no way to do with this output
Please let me know if there is a way to find real-time download size status.
FYI if you download any binary from curl, in Node.js exec command you get the real time bytes downloaded/total data.
The output that you are mentioning only happens if the docker CLI is running somewhere where there is a pseudo-tty allocated. You can force the output to not have a pseudo-tty on the command line by running the command this way:
docker pull my-image | cat
The pole will happen, and then you will get the same sort of output that you mentioned above.
It is likely that the way that you are calling the docker CLI is not allocating the pseudo-tty, causing it to not stream the progress information to standard out.
Try calling the executable with a pseudo-tty allocated to get the desired behavior.