How to "grep" body of console.log? - node.js

I am totally new to NodeJS and right now I am just doing try and error based on code I am finding.
I want to monitor my router at home. To get data, I have to do a http request via nodejs and have to store a "token" to a variable. This token is set to the end of the real request for the data.
The output of curl is:
[long html stuff]
var _httoken = 12391231849184ß
[even longer html stuff]
In bash curl I would do it like:
token=`curl -v --silent http://192.168.2.1/html/login/status.html?lang=de 2>&1 | grep _httoken | grep -o '[0-9]\+'
But when I try to get it like this:
const { exec } = require('child_process');
exec('curl -v --silent http://192.168.2.1/html/login/status.html?lang=de 2>&1 | grep _httoken | grep -o '[0-9]\+'', (err, stdout, stderr) => {
if (err) {
// node couldn't execute the command
return;
}
// the *entire* stdout and stderr (buffered)
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
I get:
exec('curl -v --silent http://192.168.2.1/html/login/status.html?lang=de 2>&1 | grep _httoken | grep -o '[0-9]\+'', (err, stdout, stderr) => {
SyntaxError: Invalid or unexpected token
At the \.
How can I get the digits stored?
Thanks in advance

Related

CLI app on Node.js How to pass the option value as an argument for the Shell command via child_process [duplicate]

This question already has answers here:
Usage of the backtick character (`) in JavaScript
(11 answers)
Closed last month.
This post was edited and submitted for review last month and failed to reopen the post:
Original close reason(s) were not resolved
How to pass the value of the --url option as an argument for the Wget command
#!/usr/bin/env node
'use strict';
const commander = require('commander');
const { exec } = require("child_process");
const program = new commander.Command();
program
.option('-u, --url <value>', 'Website address');
program.parse(process.argv);
const options = program.opts();
if (options.url) {
exec("wget ${options.url}", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
}
Output:
node app.js --url ff99cc.art
error: Command failed: wget ${options.url}
/bin/bash: line 1: ${options.url}: bad substitution
It is necessary that the --url value is passed as an argument for wget. So that when you execute the node command app.js --url example.com,she was doing wget example.com.
Solved Thanks spyrospal and ibrahim tanyalcin
The issue is how you use string interpolation to format the wget command. As mentioned here should be with backtick (`) characters instead of double quotes:
exec(`wget ${options.url}`, (error, stdout, stderr) => {
The issue is how you use string interpolation to format the wget command.
As mentioned here should be with backtick (`) characters instead of double quotes:
exec(`wget ${options.url}`, (error, stdout, stderr) => {

In Node.js, why does my spawn command produce an error?

When I run:
unzip -p /tmp/document.docx word/document.xml | sed -e 's/<\/w:p>/\\n/g; s/<[^>]\{1,\}>//g; s/[^[:print:]\n]\{1,\}//g'
It correctly extracts the text from my .docx file.
But when I try to wrap this in a Node.js program as follows:
const spawn = require("child_process").spawn;
const command = "unzip"; ;
const child = spawn("sh", ["-c", "unzip -p /tmp/document.docx word/document.xml | sed -e 's/<\/w:p>/\\n/g; s/<[^>]\{1,\}>//g; s/[^[:print:]\n]\{1,\}//g'"]);
const stdout = child.stdout;
const stderr = child.stderr;
const output = "";
stderr.on("data", function(data) {
console.error("error on stderr", data.toString());
});
stdout.on("data", function(data) {
output += data;
});
stdout.on("close", function(code) {
});
I get the following error message:
error on stderr sed: -e expression #1, char 10: unknown option to `s'
How do I fix this error?
When using a command line that way in your code, you have to think about the interpretation of the \ made by node.js and antislash the antislash. One for the node.js one for the sed command.
spawn("sh", ["-c", "unzip -p /tmp/document.docx word/document.xml | sed -e 's/<\\/w:p>/\\\\n/g; s/<[^>]\\{1,\\}>//g; s/[^[:print:]\\n]\\{1,\\}//g'"])
Look at here
#T.J Crowder
In JavaScript, the backslash has special meaning both in string
literals and in regular expressions. If you want an actual backslash
in the string or regex, you have to write two: \.

Node js - how to execute two windows commands in sequence and get the output

I am trying to execute two windows commands in sequence and get the result of the later one. Something like:
cd ${directory}
sfdx force:source:convert -d outputTmp/ --json
I have browsed and tried a bunch of third-party libraries, like node-cmd. But so far I haven't got any luck yet. As in node-cmd example:
cmd.get(
`cd ${directory}
sfdx force:source:convert -d outputTmp/ --json`,
function(err, data, stderr) {
This works very well on my macOS machine. But on Windows it tends to execute only the first command.
Is there anyway I can resolve this issue? Even some walk around for just cd {directory} + real command can be really helpful
You can try this:
const exec = require('child_process').exec;
exec(`cd dir
sfdx force:source:convert -d outputTmp/ --json`, (err, stdout, stderr) => {
if (err) {
// node couldn't execute the command
return;
}
console.log(stdout);
});
or by using && without backticks:
const exec = require('child_process').exec;
exec('cd dir && sfdx force:source:convert -d outputTmp/ --json', (err, stdout, stderr) => {
if (err) {
// node couldn't execute the command
return;
}
console.log(stdout);
});

How to exec script to set iterm2 Badge from nodejs?

I get this bash script from Iterm2 official site.
printf "\e]1337;SetBadgeFormat=%s\a" $(echo "text" | base64)
I tried exec like bellow, there is no error, but failed to set iterm2 Badge
var exec = require('child_process').exec;
exec('printf "\e]1337;SetBadgeFormat=%s\a" $(echo "text" | base64)');
setBadgeFormat.js =>
#!/usr/bin/env node
var rawBadgeFormat = 'test'
var base64BadgeFormat = new Buffer(rawBadgeFormat).toString('base64')
var setBadgeFormatCmd = 'printf "\\e]1337;SetBadgeFormat=' + base64BadgeFormat + '\\a"'
require('child_process').exec(setBadgeFormatCmd, function(error, stdout, stderr) {
if (error) console.log(error);
process.stdout.write(stdout); // this line actually do the trick
process.stderr.write(stderr);
});

Node child_process.spawn multiple commands

I wan to automate the creation and extracting of keystore.
The problem I'm facing is how to join the commands using the ' | ' symbol or similar solution.
//Original Command
var command='keytool -exportcert -storepass mypass -keypass mypass
-alias myalias -keystore mykey.keystore | openssl sha1 -binary | openssl base64';
//Arguments for the spawn
var keyArgs = [
'-exportcert',
'-storepass','mypass',
'-keypass','mypass',
'-alias','myalias',
'-keystore',"myjey.keystore",
'openssl','sha1',
'-binary',
'openssl','base64',
];
exec('keytool',keyArgs,{cwd:appCreateFolder+"/"+opt.id+"/Certificates"},function(e){
console.log(chalk.cyan('Key created'));
})
From Node.js v6 you can specify a shell option in spawn method which will run command using shell and thus it is possible to chain commands using spawn method.
For example this:
var spawn = require('child_process').spawn;
var child = spawn('ls && ls && ls', {
shell: true
});
child.stderr.on('data', function (data) {
console.error("STDERR:", data.toString());
});
child.stdout.on('data', function (data) {
console.log("STDOUT:", data.toString());
});
child.on('exit', function (exitCode) {
console.log("Child exited with code: " + exitCode);
});
Will trigger an error on node.js version less than 6:
Error: spawn ls && ls && ls ENOENT
But on version 6 and higher it will return expected result:
node app.js
STDOUT: app.js
STDOUT: app.js
app.js
Child exited with code: 0
The | symbol on the command line is called "piping" because it's like piping streams of data together. What you want is to get ahold of the stdin (Standard In) and stdout (Standard Out) streams for the commands you're executing.
For example, this is how you would spawn the echo command and pipe it's output to grep:
var spawn = require('child_process').spawn;
var echo = spawn('echo', ['The quick brown fox\njumped over the lazy dog.']);
var grep = spawn('grep', ['brown']);
echo.stdout.pipe(grep.stdin);
grep.stdout.pipe(process.stdin);
The above example spawns both the "echo" and "grep" commands. It pipes any output from the echo process's stdout stream to the grep process's stdin stream. Finally we pipe the grep process's stdout stream to the parent process's (your node process) stdin stream so you can see the output in your terminal.
The output would be "The quick brown fox" because I put a newline character in the middle and the grep only matched the first line containing "brown".
You could use the exec function to achieve the same result. Just might be harder to maintain in the future, but if all you need is to quickly run a set of piped commands, you can enter the full command line string (including pipe symbols) and pass it to exec.
var exec = require('child_process').exec;
var cmdString = 'grep "The quick brown fox\njumped over the lazy dog." | grep "brown"';
exec(cmdString, (err, stdout, stderr) => {
console.log(stdout);
});
Or instead of passing in the callback function you could just pipe the output to process.stdin if all you care about is seeing the command output.
exec(cmdString).stdout.pipe(process.stdin);
Here's a quick example of what I believe your code should look like using spawn. May require tweaks since it seems specific to what you're doing.
var keyArgs = [
'-exportcert',
'-storepass','mypass',
'-keypass','mypass',
'-alias','myalias',
'-keystore',"myjey.keystore",
'openssl','sha1',
'-binary',
'openssl','base64',
];
var keyOpts = {
cwd: `${appCreateFolder}/${opt.id}/Certificates`
};
var spawn = require('child_process').spawn;
var keytool = spawn('keytool', keyArgs, keyOpts);
var opensslBinary = spawn('openssl', ['sha1', '-binary']);
var opensslBase64 = spawn('openssl', ['base64']);
keytool.stdout.pipe(opensslBinary.stdin);
opensslBinary.stdout.pipe(opensslBase64.stdin);
opensslBase64.stdout.pipe(process.stdin);
opensslBase64.on('close', () => {
console.log(chalk.cyan('Key created.'));
});
Or using exec:
var exec = require('child_process').exec;
var cmdString = 'keytool -exportcert -storepass mypass -keypass mypass -alias myalias -keystore mykey.keystore | openssl sha1 -binary | openssl base64';
var cmdOpts = {
cwd: `${appCreateFolder}/${opt.id}/Certificates`
};
exec(cmdString, cmdOpts, () => {
console.log(chalk.cyan('Key created.'));
});

Resources