I have apache and Node.js running on Ubuntu
Is there a way to programatically check if the apache service is running with Node? If it's not running, allow Node.js to start/restart the service, also could the same code be used to run other processes like MySQL?
I'd also like to find a way to make Node execute "ps -u user" and capture the output in a js string or object
I've had a look at Node.js child processes but I can't figure it out
Thanks in advance
You can use the "exec" method of "child_process" module to execute a command from your node app and have its output passed as a parameter to a callback function.
var exec = require("child_process").exec;
exec("ps -u user", function (error, stdout, stderr) {
var myResult = stdout;
//doSomething
});
You could also use shelljs - https://www.npmjs.com/package/shelljs, which has many functions goes directly to shell and is cross-platform. ps command is not one of them, so use exec similar as with child_process.
require('shelljs/global');
exec('ps -aux | grep apache')
With exec you could start/restart service too, however you will need to run node process as root, what's not best option. Or create usergroup specifically for apache.
To run 'ps -u user' use the same. It will return you object with all info you need about processes.
exec('ps -u user');
And than continue with output as you need.
with spawn you can run shell scripts. So if you had a shell script written to check if a processes is running...something like this you should us spawn to run it. something like...
var child = spawn('sh', [__dirname+'/some-status-shell-script.sh'], {env: process.env});
Likewise you can use spawn to access your mysql db...similiar to this
Related
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}`);
});
I have setup a nodejs server on a machine where I would like to execute scripts. The command is created on the client side and is sent to the nodejs server through a variable. This command contains a bunch of spaces, along with the script and the arguments needed for it to be executed.
An example command to be executed on the machine: <script.sh> -input <inputfile> -output <outputDir> -helper_file <file>
var child = exec('$command')
This command is passed to the server inside a variable. When I try to run the command with the exec process, it stumbles on the spaces and the arguments. How do I get around this issue?
Thanks
I'm writing a test suite that requires a proxy to be booted up, and then a curl POST request needs to be made to the proxy once it is live.
This is simple to do manually via two different tabs in the terminal eg:
In one terminal window: sh ./proxy/bin/yourProxy
In another terminal window: curl -X POST http://localhost:8080/proxy
This works, but I want to have this automated.
The issue I'm running into is that when I run the first shell command, a shell opens, but another shell never opens - and I need two different shells - one for each command.
I've tried using the concurrently npm module and using sleep to make the commands synchronous - no luck
I'm exploring using node. I've tried node's spawn, exec, and execSync. Here's an example using spawn:
const { spawn } = require("child_process");
const childOne = spawn("/bin/sh", [ "-c", "curl http://www.google.com" ])
const childTwo = spawn("/bin/sh", [ "-c", "curl http://www.yahoo.com" ])
childOne.stdout.on("data", (data) => {
console.log(`childOne stdout:\n${data}`);
});
childTwo.stdout.on("data", (data) => {
console.log(`childTwo stdout:\n${data}`);
});
This produces the result of curling childOne - but child2 shows a "redirect".
Terminal output:
child2 stdout:
redirect
child stdout:
expected output from curling google.com
How do you set up Node to open n shells and execute n commands synchronously?
First you won't want need to do things such as running other processes, making network requests etc. synchronously, since they may block your main process and get your program stuck.
Second, there are no problems with the functions you've found: spawn() and exec() can run processes asynchronously, and execSync() does the same thing synchronously. The reason why curl http://www.yahoo.com prints redirect is that it IS a redirect. Try running it in your own shell, and you'll be able to find exactly the same output:
$ curl http://www.yahoo.com
redirect
i want to build a node app which allows me to send kill -9 to all child processes of one daemon.
To be clear.
We have one daemon on our server. At its start it launches a process for the communication with our clients.
When the client sends a new job to the server, a new child process is created by the daemon.
So now I want to get all child processes of the daemon, kill -9 them and then restart the daemon with systemctl restart mydaemon.service
I searched google and did not find anything that fits my issue.
What I need to say is, i want to solve this without knowing the daemons process-id, of course only if possible.
Why do I need this
Why I need to do this is because, the software the daemon belongs to, is buggy. The communication process I mentioned above is failing and is simply gone. The seller says killing all processes is possible by just restarting the daemon, which of course is not. So because the seller can't provide any solution for our problem were currently restarting the service the same way I want to automate it now. Killing all childs with SIGKILL and then restart the daemon.
Thank you very much guys.
You can find all the child processes (recursively) using a pstree utility.
Mostly likely will need to install it. On Mac, for example, you'd do: brew install pstree.
Then you can run this snippet to find all the child processes and kill them:
const child_process = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(child_process.exec);
(async () => {
const pids = await execAsync(
`pstree ${process.pid} | sed 's/[^0-9]*\\([0-9]*\\).*/\\1/' | grep -v "${process.pid}"`
);
// Join the pids into one line separated by space
const pidsString = pids.stdout.replace(/[\r\n]+/g, ' ');
await execAsync(`kill -9 ${pidsString} || true`);
})();
Please find the detailed explanation below:
pstree ${process.pid} - returns a tree of all the child processes. The output looks like this:
sed 's/[^0-9]*\\([0-9]*\\).*/\\1/' - keeps only the pids, removes the rest of the strings
grep -v "${process.pid}" - removes the current process from the list, we don't want to kill it
kill -9 ${pidsString} || true - kills the child processes with SIGKILL.
I had to do || true because pstree returns a full list of processes including itself (it also spawns ps internally). Those processes are already ended at the time when we start killing so we need it to suppress the No such process errors.
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);