How do I provide STDIN data to a J script run via jconsole.exe? - j

I want to run a J script, providing STDIN, and receive the output of the script with STDOUT.
I feel like I'm missing something blindingly obvious, but the help pages on using jconsole.exe are . . . terse.
My naive thought was that I could run the following in the cmd.exe shell to provide STDIN:
jconsole.exe script.ijs inputstring
While that works without the attempted STDIN:
C:\..\bin>jconsole.exe "C:\path\no-input-script.ijs"
success
C:\..\bin>
The no-input-script.ijs file is the following:
stdout 'success'
exit ''
I have the following script-with-input.ijs file:
input =: stdin ''
stdout 'input was ' , input
exit ''
When I run the following, the system hangs:
C:\..\bin>jconsole.exe "C:\path\script-with-input.ijs" xyz
When I then hit Ctrl+C, the script exits and I am left with the following:
C:\..\bin>jconsole.exe "C:\path\script-with-input.ijs" xyz
input was
C:\..\bin>

stdin reads input from STDIN until EOF (usually in *nix ^D). So your 'script-with-input.ijs' waits for user input or a pipe.
c:>jconsole.exe "script-with-input.ijs" hello
this is user input
^D
input was this is user input
What you, instead, are trying to do is read the arguments of the command. Those are stored in ARGV:
NB. script-with-input.ijs
input =: ARGV
echo input
exit''
Then:
c:>jconsole.exe "script-with-input.ijs" hello
┌────────────┬─────────────────────┬─────┐
│jconsole.exe│script-with-input.ijs│hello│
└────────────┴─────────────────────┴─────┘

Related

python3 reset stdin after end of file

On Linux, I want to read from stdin where stdin comes first from pipe and then from user input.
So the command looks like:
cat my-file | ./my-prog.py
After reading all the lines from the pipe:
inf = open(0, "r")
inf.readlines()
I want to get further input from user. I do it with input(). But I get EOFError: EOF when reading a line.
I need a way to reset the stdin before the call to input().
Trying sys.stdin.seek(0) gives
io.UnsupportedOperation: underlying stream is not seekable
I read that in c there is clearerr that do that but I was not able to find how to do it in python.

child.stdout.on works with read but not read -p

I'm trying to create a simple node API that would spawn a shell script and add user input from a POST call to that spawn. I created a controller called testController.js that would run a script called test.sh located in the same project
I was having a few problems writing the user input but thankfully this solution saved me.
So this really simple controller function ended up to be:
testController.js:
exports.create_task = function (req, res) {
var spawn = require("child_process").spawn;
var spawned = spawn("sh", ["/var/www/html/node_test_proj/test.sh"]);
spawned.stdout.on("data", function (data) {
console.log("In stdout");
spawned.stdin.write(req.body.name + "\n");
spawned.stdin.write(req.body.number + "\n");
});
res.send("posted");
};
My shell script would basically just take a name and number and export those details into a file:
test.sh:
#!/bin/bash
echo "Please input your name"
read name
echo "Please input your number"
read number
echo "Your name is $name and number $number" > knowingthis.txt;
Simple enough; does what it's supposed to and (given name abc and number 123) prints out:
your name is abc and number 123
However, to simplify things further I decide to replace the unnecessary echo statements with something simpler i.e read -p. Now my modified script becomes:
#!/bin/bash
read -p "Please input your name: " name;
read -p "Please input your number: " number;
echo "Your name is $name and number $number" > knowingthis.txt;
Lo and behold! Now when I spawn the script it no longer works; it doesn't even log the "In stdout" so that means that it's never really going in that clause, it simply exports the file with variables empty in the sentence, leaving the output to be:
your name is and number
I thought maybe there's something wrong with the script, so I ran it directly, but it was working fine. Why is it working with read and not read -p? Is there something I need to change in my function? Is it not a normal stdout stream but something else?
The man page section, or info page or website page, for builtin commands under read option -p says (emphasis added)
Display prompt, without a trailing newline, before attempting to read any input. The prompt is displayed only if input is coming from a terminal.
'coming from' means directly, i.e. only if file descriptor #0 (stdin) of the shell process is an open file which is a terminal and not a (redirected) disk file or pipe or socket. When nodejs spawns a child process, the child's stdin is a pipe from nodejs, and the child's stdout and stderr are pipes to nodejs; they (all) are not terminals.
OTOH echo writes to stdout unconditionally (regardless of what type of file it is).

Sending input to a program that accepts input via stdin

I have shell script that triggers after it receives an input from the stdin. It works as follows:
> ./ft/ft_0 model_32 -
>
> start_task_u
As you see above the executable ft_0 model_32 accepts input from the stdin which is denoted by - (where input entered is start_task_u). The user enters the input in the stdin and the program gets triggered. How could I do this with spawn in NodeJS?
I could start the process using spawn as follows:
spawn('./ft/ft_0',['model_32','-'])
but how could I send the input using the standard input after the program has started? I need to send start_task_u after the program has started and receive all the outputs that the shell script prints on the console.
Pass config option to inherit stdin and stdout from the parent process. Please find below
spawn('./ft/ft_0',['model_32','-'], {
stdio: [
0,
1,
]
})
Doc Link - https://nodejs.org/dist/latest-v10.x/docs/api/child_process.html#child_process_child_process_spawn_command_args_options

Pipe Input on a timer

I have a program that asks for input but it takes a while to load up.
I need a bash script that will pipe out the output into a named pipe.
I need a command that will cause my echo to insert my input after the program prompts for input. This is my command right now but it pipes in the input before my prompt.
echo "R" | nc localhost 123 > fifo
This will result in the following output:
usernname#name:
R
Please enter in an input (R, Q, T):
So my command needs to "wait" until my program prompts then pipe in the input. Any ideas? This needs to be in a bash script
You can use sleep:
(sleep 3; echo "R") | nc localhost 123 > fifo
Obviously this has a race condition, and so for industrial applications you should use expect instead.

Unix: What does cat by itself do?

I saw the line data=$(cat) in a bash script (just declaring an empty variable) and am mystified as to what that could possibly do.
I read the man pages, but it doesn't have an example or explanation of this. Does this capture stdin or something? Any documentation on this?
EDIT: Specifically how the heck does doing data=$(cat) allow for it to run this hook script?
#!/bin/bash
# Runs all executable pre-commit-* hooks and exits after,
# if any of them was not successful.
#
# Based on
# http://osdir.com/ml/git/2009-01/msg00308.html
data=$(cat)
exitcodes=()
hookname=`basename $0`
# Run each hook, passing through STDIN and storing the exit code.
# We don't want to bail at the first failure, as the user might
# then bypass the hooks without knowing about additional issues.
for hook in $GIT_DIR/hooks/$hookname-*; do
test -x "$hook" || continue
echo "$data" | "$hook"
exitcodes+=($?)
done
https://github.com/henrik/dotfiles/blob/master/git_template/hooks/pre-commit
cat will catenate its input to its output.
In the context of the variable capture you posted, the effect is to assign the statement's (or containing script's) standard input to the variable.
The command substitution $(command) will return the command's output; the assignment will assign the substituted string to the variable; and in the absence of a file name argument, cat will read and print standard input.
The Git hook script you found this in captures the commit data from standard input so that it can be repeatedly piped to each hook script separately. You only get one copy of standard input, so if you need it multiple times, you need to capture it somehow. (I would use a temporary file, and quote all file name variables properly; but keeping the data in a variable is certainly okay, especially if you only expect fairly small amounts of input.)
Doing:
t#t:~# temp=$(cat)
hello how
are you?
t#t:~# echo $temp
hello how are you?
(A single Controld on the line by itself following "are you?" terminates the input.)
As manual says
cat - concatenate files and print on the standard output
Also
cat Copy standard input to standard output.
here, cat will concatenate your STDIN into a single string and assign it to variable temp.
Say your bash script script.sh is:
#!/bin/bash
data=$(cat)
Then, the following commands will store the string STR in the variable data:
echo STR | bash script.sh
bash script.sh < <(echo STR)
bash script.sh <<< STR

Resources