How to send control C node.js and child_processes - windows

Hello I want to send to the child_process, for example, ping 8.8.8.8-t, that is, an infinite number of ping. And some of the iterations I want to stop this command and execute a new, but in this case I do not want to kill a child process.
Example:
var spawn = require('child_process').spawn('cmd'),
iconv = require('iconv-lite');
spawn.stdout.on('data', function (data) {
console.log('Stdout: ', iconv.decode(data, 'cp866'));
});
spawn.stderr.on('data', function (data) {
console.log('Stderr: ', iconv.decode(data, 'cp866'));
});
spawn.stdin.write('ping 8.8.8.8 -t'+ '\r\n');
spawn.stdin.write(here control-c...); // WRONG
spawn.stdin.write('dir' + '\r\n');

I found your previous question. Looks like you are trying to create/emulate a terminal from within node.js. You can use readline for reading and writing from a terminal.
To write control character, you can see the example from its docs :
rl.write('Delete me!');
// Simulate ctrl+u to delete the line written previously
rl.write(null, {ctrl: true, name: 'u'});
To directly answer the question, to pass special characters you will need to pass their ASCII values. Ctrl + C becomes ASCII character 0x03. Value taken from here.
spawn.stdin.write("\x03");

Related

What are the rules that Vala's Process.spawn_command_line_async follows in interpreting CLI arguments?

Specifically, how does it interpret arguments that are in quotes or that feature redirects from standard input (e.g. <)?
I've got the following string:
string cmd = "mail -s 'Work Order #%s' -c %s -r email#server.com %s < email.txt".printf(wo.get_text(), ownmail, outmail.get_text());
When I use
Posix.system(cmd);
The command runs as expected and an email is sent, with the body taken from email.txt.
When I use
Process.spawn_command_line_async(cmd);
I get the error from the mail command that 'option -c is not found' or words to that effect. When I lose the quotes around Work Order #%s and instead escape the spaces, the email sends (with the subject line containing the back slashes) but instead of getting the body of the message from email.txt, it treats email.txt as another recipient of the email (it shows up in my inbox with 'email.txt' under the To: section). The < is being ignored or dropped. To check things out, I used
Process.spawn_command_line_async("echo %s".printf(cmd));
This showed me that the quotes around the subject line were being dropped but the < was still there. I can use Posix.system() in my program but for the sake of simplicity and reducing dependencies (and being more idiomatic), I'd prefer to use Process.spawn_command_line(). What am I missing?
Thank you!
You probably want to play around with Shell.quote() and Shell.unquote() in your "".printf() arguments.
The Vala Process.spawn_command_line_async() function is bound to GLib's g_spawn_command_line_async () function. So a good place to start looking for more details is the GLib documentation. The GLib documentation states g_spawn_command_line_async() uses g-shell-parse-argv to parse the command line. This parses the command line so the "results are defined to be the same as those you would get from a UNIX98 /bin/sh, as long as the input contains none of the unsupported shell expansions."
Also on that page are g_shell_quote () and g_shell_unquote (). These functions are bound to Vala as Shell.quote () and Shell.unquote ().
mail only accepts the body of the message from STDIN and g_spawn_command_line_async() won't handle the redirect. So you will either need a command line tool that takes the body as an argument or using something like Subprocess instead.
Thanks to both AIThomas and Jens sending me looking in the right direction, I was able to get it working with the following code:
static int main(string[] args) {
string subject = "-s " + Shell.quote("Work Order #123131");
string cc = "-c ccemail#org.org";
string frommail = "-r " + "senderemail#org.org";
string[] argv = {"mail", subject, cc, frommail, "destinationemail#org.org"};
int standard_input;
int child_pid;
Process.spawn_async_with_pipes (
".",
argv,
null,
SpawnFlags.SEARCH_PATH,
null,
out child_pid,
out standard_input,
null,
null);
FileStream instream = FileStream.fdopen(standard_input, "w");
instream.write("This is what will be emailed\n".data);
return 0;
}

How to pass variable values to sendKeys in casperjs

I have the following issue with sendKeys in casperjs.
I am trying to pass the port as an option into casperjs and this is working, but when i try to use the port value with casper.cli.get it doesn't work in sendKeys!!!
var casper = require('casper').create();
casper.echo("Casper CLI passed args:");
require("utils").dump(casper.cli.args);
casper.echo("Casper CLI passed options:");
require("utils").dump(casper.cli.options);
if (casper.cli.has("ip") === false) {
casper.echo("Usage: casper.js test modify_port.js --ip=<x.x.x.x> --port=<xxxxx>").exit();
}
if (casper.cli.has("port") === false) {
casper.echo("Usage: casper.js test modify_port.js --ip=<x.x.x.x> --port=<xxxxx>").exit();
}
...
casper.then(function() {
test.assertTextExists("Change", "Data Base - Change - port");
this.sendKeys('input[name="Params.port"]', casper.cli.get("port"));
this.click('input[name="Apply"]');
});
The above way seems not to work and it doesn't give me also no error msg.
But when i hard code the port in the sendKeys line then i see that the port is changed, like:
this.sendKeys('input[name="Params.port"]', '29999');
This is also working fine (hard coded):
var myPort = '29999'
this.sendKeys('input[name="Params.port"]', myPort);
But this again is not working:
var myPort = casper.cli.get("port")
this.sendKeys('input[name="Params.port"]', myPort);
Thanks in adv. for your time
After some more readings I stepped over the part where casperjs documentation is saying about Raw parameter values.
So, I figured out to use my parameter in this way:
this.sendKeys('input[name="Params.port"]', casper.cli.raw.get('port'));
When passing variables into sendKeys they will not appear in the form unless they are preceded with an empty string "".
this.sendKeys("selector", "" + variable);
I guess this may be because sendKeys can only handle variables of type string.
Source

Print current frame during command line render?

Is there a way to basically print my own output during a command line render?
Let's say I don't need/want all the other output that maya spits out by default, I know you can change the verbosity level, but there's very specific things I'd like to output but I can't figure it out. I currently render out the verbosity output to file, so I wanted to print in the terminal (I'm using MAC) the frame that the render is currently up to.
This may just be simple minded, but here's what I tried:
Render -preFrame "print `currentTime -q`;" -s 1 -e 20 -rd /render/directory/ maya_file.mb
Obviously, -preFrame expects a string, according to the docs this can take mel commands, but obviously this is limited to certain commands, I'm assuming the currentTime command is pulling the information from the timeline in maya, not queering it from the Renderer it self... When I run the above command, straight away, it spits out this: -bash: currentTime: command not found and soon after the render fails/doesn't start.
Idealy, I'd like to print the following as it starts each frame:
"Started rendering frame XXXX at TIME GOES HERE", that way, I can quickly look at the terminal, and see if the renderer has failed, stuck or where it's up to and when it started it.
So my question is, seeing is currentTime is a mel command used from within Maya, is there another way I could print this information?
Cheers,
Shannon
After many hours of searching for this answer, I ended up finding out that you can start maya as an interactive shell. By doing this, I was able to source a script as I opened it, and run whatever I want into memory as If I had Maya open at the time.
/Applications/Autodesk/maya2014/Maya.app/Contents/MacOS/maya -prompt -script "/Volumes/raid/farm_script/setupRender.mel"
In the setupRender.mel file, I was able to assign variables, containing options for renders etc, in doing this, I was also able to create a global variable for the frame number, and increment it during the preFrame callback, like so:
int $startFrame = 100;
int $endFrame = 1110;
global int $frameCount = 0;
string $preRenderStatistics = "'global int $frameCount; $frameCount = " + $startFrame + ";'";
string $preFrameStatistics = "'print(\"Rendering frame: \" + $frameCount++)'";
string $additionalFlags = "";
string $sceneFilePath = "'/Volumes/path/to/file/intro_video_001.mb'";
system("Render -preRender " + $preRenderStatistics + " -preFrame " + $preFrameStatistics + " -s " + $startFrame + " -e " + $endFrame + " -x " + $additionalFlags + " " + $sceneFilePath);
This is a very simplified version of what I currently have, but hopefully this will help others if they stumble across it.
Take a look at the pre render layer MEL and/or pre render frame MEL section of the Render Settings.
It expects MEL, so you'll either need to write it in MEL or wrap your python in MEL. For such a simple use, I'd say just write it in MEL:
print `currentTime -q`

Node.js: How to send control C to child process

I am writing one web-like linux shell using node.js + socket.io. Simple command like, ls, cd are working well.
But when issue command like ping google.com, the stdout is printing endlessly.
I tried to send Ctrl +C to stdin, but no luck.
1) spawn 'bash' process
spawn = require('child_process').spawn;
var sh = spawn('bash');
2) send bash stdout to socket.io
sh.stdout.on('data', function(data) {
console.log('stdout' + data);
listener.sockets.emit("stdout",new Buffer(data));
});
3) Sending Ctl C (\x03) to bash's stdin.
var listener = io.listen(server);
listener.set('log level',1);
listener.sockets.on('connection', function(client){
client.on('message', function(data){
if(data === "KILL") {
console.log('!!!!' + data);
sh.stdin.write('\x03');
client.broadcast.send(new Buffer("KILLING "));
//return;
};
console.log(data);
sh.stdin.write(data+"\n");
client.broadcast.send(new Buffer("> "+data));
});
});
I am stuck at this point. Seems like
Try process.kill(sh.pid). I use this to kill workers in a cluster when my master process shuts down. sh.signalCode should be equal to SIGTERM. Of course, I have no idea if this works on Windows.
try stdout.push(null).
I tried it on node 12. This will not kill your child process instead it will tell you output stream that there is no more input stream.

pushing tty output to node

For the satisfaction of my curiosity gene i'd like to play with bash/node combo.
I don't know how to make those 2 talk together. I just had a great smile on my face finding about TTY.JS ;-)
How do I feed terminal's output (sdtout?) to node? I thought about redirecting the stream to file and read it with node through 'fs' module. But there must be some prettier way I bet
thanks in advance.
Something like this should send terminal output to node
var app = require('express').createServer(),
io = require('socket.io').listen(app),
sys = require('util'),
exec = require('child_process').exec;
app.listen(4990);
io.sockets.on('connection', function(socket) {
socket.on('console', function(command, callBack) {
// client sends {command: 'ls -al'}
function puts(error, stdout, stderr) {
socket.emit('commandresult', stdout);
}
exec(command.command, puts);
});
});​
Hope this helps

Resources