Why we use -i or --interactive in Node.js if we can easily jump into the REPL with just a simple command node ?
I have read the documentation but the documentation is a little bit confusing:
Reference Link
Opens the REPL even if stdin does not appear to be a terminal.
I understand the part Opens the REPL but didn't understand what does even if stdin does not appear to be a terminal mean ?
When executing node in a text terminal by itself, the program will provide a REPL for interactive use by a human. However, it might be the case that node is not run in a terminal, or that it was given a script to execute in a non-interactive fashion, which makes node run the given script without providing a REPL. For example, this would likely be the case for a Node.js child process which is given input and output streams between the parent process and the child process. As another example, the command below will not execute node in interactive mode:
echo "console.log('Hello');" | node
The -i option is designed to override this automatic decision, by forcing node to provide a REPL regardless of whether it has detected the presence of a text terminal. This may be particularly useful for making non-user-facing programs which streamline the REPL's inputs and outputs to another application.
Node.js itself provides an additional layer on top of input and output streams for those which are associated with a text terminal. According to the TTY module:
When Node.js detects that it is being run with a text terminal ("TTY") attached, process.stdin will, by default, be initialized as an instance of tty.ReadStream and both process.stdout and process.stderr will, by default be instances of tty.WriteStream.
If you run node and type in process.stdin.isTTY, it will output true. The following command, on the other hand, will print undefined:
echo "console.log(process.stdin.isTTY)" | node
Related
I'd like to run a remote bash shell that is fully interactive.
The client side should be able to send commands to this bash process and get the outputs interactively.
This means that, just like in a local bash prompt, the correlation between commands and their respected responses isn't necessarily guaranteed, since we may get outputs from a previous command that runs in the background, after running another command.
It works when I run separate bash process and use pipes:
bash 2>&1 | tee file
bash > file 2>&1
However, if I need to send control characters like Tab for auto-completion or Ctrl+C, in case we want to terminate the current command.
It may sound similar to SSH protocol, but I'd like to experiment with this option of running an alternative remote shell, with different access control and UI experience.
So, my question is: How do I pass the control character to the remote bash process (for example, the auto-completion) and get back the results (for example, list of choices for auto-completion)?
NOTE: I don't wish to develop bash equivalent shell script, but just build a proxy process that is able to pass both data and control characters and provide seamless bash experience as in local /ssh mode.
I need to do a interactive shell programmatically (in Node.js, but any language will do).
The most important is that I want to start a REPL of any language (node, ruby, erlang etc.) and be able to get autocompletion
pri\t
which I want to get output in stderr (for instance)
print() println() printf()
And because it's in language REPL compgen cannot be used.
I've tried many ways but it seems that it fails because shell can't be interactive while opened programmatically.
Launchin /bin/sh -i just yeilds errors like:
bash: cannot set terminal process group (XXXX): Inappropriate ioctl for device
I've heard that I can't start interactive shell without the terminal, but when doing SSH autocompletion does work which means it can be emulated in some way.
I'd appreciate Your help. I can't continue my work without finding a solution to this.
You can emulate a terminal using a pseudoterminal. This is how ssh does it. There's a lot to using a pseudoterminal though and the SO answer box isn't big enough for all of it. So check the man page for pty(7).
So I am using node.js' built-in debugger and trying to skip the "break on first line" that it performs by passing in a delayed "c" keypress (c=continue) using echo, as such:
(sleep 1; echo -ne 'c\n') | node debug ~/src/main.js
It works as expected, but the node debugger no longer seems to accept keyboard input afterwords. I assume the piping in bash is doing something to cause node to ignore the keyboard. Anyone know how I can achieve the same result but maintain keyboard input to the node program?
Because node is being run in a pipeline, its input file descriptor is open to the pipeline, not to the console.
A common way to feed input to a process and then allow the user to interact is to use expect or pexpect.
I have a program that needs to start another program. On my mac I did this using system("open path"), but on linux that doesn't work. and using system(./path) is not what I want since than it overtakes the running program.
So is there any way to get the same behaviour as the mac 'open path' command on linux?
(linux noob btw:p)
If you're running the application in a GUI environment, this should be possible but the approach is different. You need to start a new terminal instance explicitly.
Determine the path to your terminal application. This depends on the linux distribution.
Next, check the documentation of that particular terminal application and find out how it can be started to run an application (your application) instead of a shell. This probably involves using some application-specific command line options. Test that in a terminal window, until you have a command line that gives you the desired result. Things could get a little tricky if your application needs command line arguments as well. Use the -- option where necessary.
Then, all you need to do is run that command line from your "parent" application. I would advise however to not use system(). The exec... family functions (using fork and wait) provide better control.
I have this node.js server which, once spawned, expects some input from stdin. The inputs shouldn't be given straight away: I need to wait for some event before giving them (e.g. a connection from somebody). If I give the commands and close the shell, the server shuts itself down. I would like to give the input to the server and close my shell (effectively leaving the server running).
I know that to run a process in background I need to do for example node my_server.js &, but this prevents the input from the command line. I would like to give this input AND then put it in background. Modules like forever puts it in the background automatically without letting me giving the inputs through stdin.
Moreover putting the script in background kills anyways the server when closing the shell.
Any suggestion?
Thanks
I did a quick test just using gedit in Ubuntu 12.04, and it worked.
Start your node app like so "node app.js arg1 arg2" however you want to and hit enter to start the program. Then hit CTRL-z once your program has started running. This gives you the terminal back but stops the process in the background. To let it run in the background now, simply "bg" and hit enter. This will let the process keep running now but in the background.
You can confirm you are still up with the command "ps -ef | grep node" which should show your program still running.
However, this does still leave the node process attached to the terminal window so when you close the terminal window it will close the process. But I think this will get you most of what you seem to be looking for quick and easy.
You asked for any suggestion, so here it is: make your server able to start without user interaction. The simplest way to do it is probably to create a file containing exactly the input needed by the server, then starting it like this:
node my_server.js < my_input.txt &
If the input needed depends on what the server outputs (ouch), use expect(1). If possible, subvert the whole thing and use a module like commander to get your inputs from the command line instead of stdin.