Writing to terminal stdout can be converted to stdin? - linux

When I run "cat /bin/bash",the final interactive prompt becomes
sh-5.0$ 1;2c1;2c
sh: 1: command not found
sh: 2c1: command not found
sh: 2c: command not found
sh-5.0$
And when I press "Enter", it runs something! The cat command only writes to stdout, why there are some bytes being put into stdin? Is this a vulnerability?

Some terminals and emulators have various "answerback" facilites where they send some text back to the computer upon reception of certain control codes. It seems likely that your bash binary contained some such control code.
And yes, this can be a vulnerability, especially if the response text can also be controlled by control codes (which one hopes it can't, nowadays, but one never knows...)
More here: https://unix.stackexchange.com/questions/15101/how-to-avoid-escape-sequence-attacks-in-terminals

# cat > file
Awaits input from user, type desired text and press CTRL+D (hold down Ctrl Key and type ‘d‘) to exit. The text will be written in test2 file. You can see content of file with following cat command.
in your case
# cat /bin/bash > fileoutput

Related

Vim run shell and see output

I'm trying to run an unsaved buffer in a shell command and have a history of the output
console.log("test")
Then, :w !node does what is expected, test is outputted, but once I click enter, the output disappears, and doesn't even show in :messages:
How can I find it?
If you open a Vim buffer and type in one or more shell commands each on "his" own line. Like:
ls /home
ls /root
Then you can type the command:
:%!bash
and not only will it run the commands on each line one after the other, it will also overwrite the buffer with the output of each command in chronological order, then you can do whatever you want with it :-)
I hope it was helpful :)
BTW: if you want to run a command in Vim and get the output in your buffer, then you can just double tap the exclamation mark in NORMAL MODE and the command line in the bottom will show
:.!
then you just type in your command and press enter. :)
easy peachy lemon squeeze :)
note: I learned that last one by mistake
What :w !cmd does it pipes your current buffer contents into cmd's stdin. When you don't need this you should simply execute :!cmd instead.
:messages serve to show an important log data printed by specially dedicated :echom[sg] command, not some random stuff from terminal windows. So the output from "node" process will not and should not ever get there.
You can put the process' stdout into the current buffer by using :r[ead] command, e.g.
:r !node

Linux Shell script executed but not return to command prompt

I have a script that runs one of the following line
sudo -u $USER $SUDOCMD &>>stdout.log
The sudo command is a realtime process that print out lots of stuff to the console.
After running the script each time, the script does not return to the command prompt. You have to press enter or ctrl + c to get back to the command prompt.
Is there a way to to do it automatically, so that I can get a return value from the script to decide whether the script runs ok or failed.
thanks.
What is probably happening here is that your script is printing binary data to the TTY rather than text to standard output/error, and this is hiding your prompt. You can for example try this:
$ PS1='\$ '
$ (printf "first line\nsecond line\r" > $(tty)) &>> output.log
The second command will result in two lines of output, the second one being "mixed in" with your prompt:
first line
$ cond line
As you can see the cursor is on the "c", but if you start typing the rest of the line is overwritten. What has happened here is the following:
You pressed Enter to run the command, so the cursor moved a line down.
The tty command prints the path to the terminal file, something like "/dev/pts/1". Writing to this file means that the output does not go to standard output (which is usually linked to the terminal) but directly to the terminal.
The subshell (similar to running the command in a shell script) ensures that the first redirect isn't overridden by the second one. So the printf output goes directly to the terminal, and nothing goes to the output log.
The terminal now proceeds to print the printf output, which ends in a carriage return. Carriage return moves the cursor to the start of the line you've already written to, so that is where your prompt appears.
By the way:
&>> redirects both standard output and standard error, contrary to your filename.
Use More Quotes™
I would recommend reading up on how to put a command in a variable

Disable pagination on the command line

I am trying to write a script using the python module pexpect that will connect to a server and execute commands like you are typing at the command line.
So for example, you can have something like:
child = pexpect.spawn('/usr/bin/ssh user#example.com')
child.sendLine('ls -al')
or whatever command you want to send. It will act like you are typing in a terminal.
In my script, I am trying to run a command using the sendLine() API that essentially dumps out a bunch of info to the command line. But there is a pagination that requires there to be another command where you have to press a key to continue to get to the next command.
So for example:
[Some info]
--------------- To continue, press any key. To quit, press 'q'. ---------------
[Some more info]
Is there a way that I can turn pagination off or a command I can send before I try to dump the info to the command line to turn it off?
In Linux:
You can use redirection to skip the pager(more or less). If it is important to display the output on screen, the output can be redirected to tee.
For example in man ls; ls, the man command expects the user to press q for termination and then ls is executed. To execute both the commands simultaneously without user intervention, it can be done as man ls | tee; ls. If displaying the output is not mandatory, it can be redirected to /dev/null as well.
For additional help, please specify the exact command that you are trying to execute on the remote server.
In Python: When using pexpect, the user activity can be automated if the intermediate output is known in advance. You can use expect function to wait for a particular output and then take necessary action(for example using sendLine).

How to show full output on linux shell?

I have a program that runs and shows a GUI window. It also prints a lot of things on the shell. I need to view the first thing printed and the last thing printed. the problem is that when the program terminates, if I scroll to the top of the window, the stuff printed when it began is removed. So stuff printed during the program is now at the top. So that means I can't view the first thing printed.
Also I tried doing > out.txt, but the problem is that the file only gets closed and readable when I manually close the GUI window. If it gets outed to a file, nothing gets printed on the screen and I have no way to know if the program finished. I can't modify any of the code too.
Is there a way I can see the whole list of text printed on the shell?
Thanks
You can just use tee command to get output/error in a file as well on terminal:
your-command |& tee out.log
Though just keep in mind that this output is line buffered by default (4k in size).
When the output of a program goes to your terminal window, the program generally flushes its output after each newline. This is why you see the output interactively.
When you redirect the output of the program to out.txt, it only flushes its output when its internal buffer is full, which is probably after every 8KiB of output. This is why you don't see anything in the file right away, and you don't see the last things printed by the program until it exits (and flushes its last, partially-full buffer).
You can trick a program into thinking it's sending its output to a terminal using the script command:
script -q -f -c myprogram out.txt
This script command runs myprogram connected to a newly-allocated “pseudo-terminal” (or pty for short). This tricks myprogram into thinking it's talking to a terminal, so it flushes its output on every newline. The script command copies myprogram's output to your terminal window and to the file out.txt.
Note that script will write a header line to out.txt. I can't find a way to disable that on my test Linux system.
In the example above, I assumed your program takes no arguments. If it does, you either need to put the program and arguments in quotes:
script -q -f -c 'myprogram arg1 arg2 arg3' out.txt
Or put the program command line in a shell script and pass that shell script to the script command.

Linux Terminal: typing feedback gone, line breaks not displayed

From time to time I have to run a command-line tool (a Python script) whose output seems to break my terminal.
After the execution is finished, the typing feedback is gone (I can't see what I'm typing), and also line breaks are not displayed. This happens if the terminal is started remotely via Putty, and also locally when using gnome-terminal.
For example, after the problem happens, if I type ENTER pwd ENTER, I would expect to see:
[userA#host006 ~]$
[userA#host006 ~]$ pwd
/home/userA
[userA#host006 ~]$
But actually the output is:
[userA#host006 ~]$ [userA#host006 ~]$ /home/userA
[userA#host006 ~]$
The only way to fix it is to close that terminal and start a new one.
Maybe be related: the script output contains some terminal-based formatting (e.g. invert foreground/background to highlight some status messages). If I dump this output to a file I can see things like [07mSome Message Here[0m.
Any ideas what I could do to prevent this?
Execute the command reset and your terminal should be restored (reference).
This issue happens generally when dumping binary data to the terminal STDOUT which when the escape codes received are processed can do anything from change the color of the text, disable echo, even change character set.
The easy way to avoid this is to ensure you do not dump unknown binary data to the terminal, and if you must then convert it to hexadecimal to ensure it doesn't change the terminal settings.
To elaborate on Joshua Briefman's answer, executing reset -c will only reset the control characters responsible for your problem:
tset, reset - terminal initialization
Usage: tset [options] [terminal]
Options:
-c set control characters
-e ch erase character
-I no initialization strings
-i ch interrupt character
-k ch kill character
-m mapping map identifier to type
-Q do not output control key settings
-r display term on stderr
-s output TERM set command
-V print curses-version
-w set window-size
Also note the following form the command's manual:
Note, you may have to type
<LF>reset<LF>
(the line-feed character is normally control-J) to get the terminal to work, as carriage-return may no longer work in the abnormal state. Also, the terminal will often not echo the command.

Resources