monitoring and logging /dev/pts/1, under linux - linux

I want to monitor and log a pseudo-terminal device /dev/pts/12 (for debugging purposes), i.e. I want to see what gets written to the terminal and I do not want any process using the terminal to notice.
The obvious solution
cat /dev/pts/1
cat </dev/pts/1
does not work: at best, it seems to capture only keystrokes.
In other words, I'd like to have something analogous to the output of
script -t file.timings typescript ;
but I also need the keystrokes. Reptyr -l $PID is another program that might help: it redirects
the output of a process $PID to another /dev/pts or pipes.

For normal tty's you got screendump or even cat the vcs file but afaik there is no way to do that on a pseudo-terminal, at least the easy way, maybe you should look this:
Conspy
Hope this helps

Related

Linux: using the tee command via ssh

I have written a Fortran program (let's call it program.exe) with does some simulation for me. Via ssh I'm logging ino some far away computers to start runs there whose results I collect after a few days. To be up-to-date how the program proceeds I want to write the shell output into a text file output.txt also (since I can't be logged in the far away computers all the time). The command should be something like
nohup program.exe | tee output.txt > /dev/null &
This enables me to have a look at output.txt to see the current status even though the program hasn't ended its run yet. The above command works fine on my local machine. I tried first with the command '>' but here the problem was that nothing was written into the text file until the whole program had finish (maybe related to the pipe buffer?). So I used the workaround with 'tee'.
The problem is now that when I log into the computer via ssh (ssh -X user#machine), execute the above command and look at output.txt with the VI editor nothing appears until the program has finished. If I omit the 'nohup' and '&' I will not even get any shell output until it has finished. My thought was that it might have to do something with data being buffered by ssh but I'm rather a Linux newbie. For any ideas or workaround I would be very grateful!
I would use screen utility http://www.oreillynet.com/linux/cmd/cmd.csp?path=s/screen instead of nohup. Thus I would be able to set my program to detached state (^A^D) reconnect to the host, retrieve my screen session (screen -r)
and monitor my output as if I never logged out.

Use of tee command promptly even for one command

I am new to using tee command.
I am trying to run one of my program which takes long time to finish but it prints out information as it progresses. I am using 'tee' to save the output to a file as well as to see the output in the shell (bash).
But the problem is tee doesn't forward the output to shell until the end of my command.
Is there any way to do that ?
I am using Debian and bash.
This actually depends on the amount of output and the implementation of whatever command you are running. No program is obliged to print stuff straight to stdout or stderr and flush it all the time. So even though most C runtime implementation flush after a certain amount of data was written using one of the runtime routines, such as printf, this may not be true depending on the implementation.
It tee doesn't output it right away, it is likely only receiving the input at the very end of the run of your command. It might be helpful to mention which exact command it is.
The problem you are experienced is most probably related to buffering.
You may have a look at stdbuf command, which does the following:
stdbuf - Run COMMAND, with modified buffering operations for its standard streams.
If you were to post your usage I could give a better answer, but as it is
(for i in `seq 10`; do echo $i; sleep 1s; done) | tee ./tmp
Is proper usage of the tee command and seems to work. Replace the part before the pipe with your command and you should be good to go.

Limit output of all Linux commands

I'm looking for a way to limit the amount of output produced by all command line programs in Linux, and preferably tell me when it is limited.
I'm working over a server which has a lag on the display. Occasionally I will accidentally run a command which outputs a large amount of text to the terminal, such as cat on a large file or ls on a directory with many files. I then have to wait a while for all the output to be printed to the terminal.
So is there a way to automatically pipe all output into a command like head or wc to prevent too much output having to be printed to terminal?
I don't know about the general case, but for each well-known command (cat, ls, find?)
you could do the following:
hardlink a copy to the existing utility
write a tiny bash function that calls the utility and pipes to head (or wc, or whatever)
alias the name of the utility to call your function.
So along these lines (utterly untested):
$ ln `which cat` ~/bin/old_cat
function trunc_cat () {
`old_cat $# | head -n 100`
}
alias cat=trunc_cat
Making aliases of all your commands would be a good start. Something like
alias lm="ls -al | more"
alias cam="cat $# | more"
Perhaps using screen could help?
this makes me think of bash-completion.
As complete command in bash enables you to specify handler when a program is not found,
what about write your own handler and clear $PATH, in order to execute every command with redirection to a filtering pipe?
#Did not try it myself.
Assuming you're working over a network connection, like ssh, into a remote server then try piping the output of the command to less. That way you can manage and navigate the output from the program on the server better. Use 'j' and 'k' to move up and down per line and 'ctrl-u' and 'ctrl-d' to move 1/2 a page up and down. When you do this only the relevant text (i.e. what fits on the screen) will be transmitted over the network.

See GNOME Terminal output in virtual console

I've got a program running in a GNOME Terminal, but the screensaver is acting up and won't let me back in with my password. While waiting for a fix for the gnome-screensaver bug, is there some way to see the output (or even take over the process) in a virtual console (Ctrl-Alt-F1) without being able to interact with the GNOME Terminal?
Clarification: The original issue was the screensaver, but the question I'd like answered is how to see the output from a process running in another terminal, after starting the process without any logging to file. I'm guessing it should be possible to set the output device of a process from a different shell? Or is it possible to put a process in another shell into background mode, and get it into the foreground in the current shell? Or even ask GNOME Terminal to redirect or copy the output?
I've had luck in the past killing the screensaver from a virtual console, unlocking X session.
# Get the pid (xscreensaver, gnome-screensaver, etc.)
ps -f -u $(whoami) | grep screensaver
kill -9 12345 # Replace 12345 with the real pid
EDIT: Seems like this has been thought of, and you should use one of these commands, depending on which screensaver program you use:
xscreensaver-command -exit
gnome-screensaver-comand --exit
See the man page for those commands for more details.
Usual way is to pipe the output to a file, like program > program.log
Do tail -f program.log in another tab of Gnome console, and the same in the non-X console.
Alternatively, use tee to duplicate the output in the same console: program | tee program.log
ssh in to the box. kill the screensaver. su to become root and kill -9 if it's really acting up.
Usually Gnome-Terminal displays the output of one vty out of /dev. So just connect your console to that vty.
Launch program with screen.
Open another terminal, launch screen -x and you have two terminals acting like one. Try it, it's fun :)

redirect the stdin to come from a different terminal using Bash

I'm wondering how one would go about redirecting the stdin of a script from the current xterm session i.e. /dev/pts/0 to one that is also running i.e /dev/pts/1 using bash? I have a bash script that opens 3 xterm windows and I want to get input from only one of those windows and I cannot figure out how to do it. Any help is appreciated! thanks.
EDIT (Moved from below -- OP submitted this clarification as an answer)
I guess I should have clarified what I wanted to do. I will start a script from a pty, let's say it's /dev/pts/3. This script will open 3 xterminals, lets say: /dev/pts/0, /dev/pts/1, and /dev/pts/2. These 3 new ptys are what the user is going to see. The script asks the user for some input and I want the input of the user to be typed into /dev/pty/1 and the program should get it's info from there. However I've tried to do this and it doesn't work. Here's a snippet of my code.
exec</dev/pts/1
echo
echo "Would you like to search for more info?" 1>/dev/pts/1
read answer
case $answer in
y) echo "YES" ;;
n) echo "NO" ;;
*) echo "y/n only!";;
esac
The case statement at the end is just a little placeholder to see if the input actually worked.
Maybe you could tweak ttyecho for your needs?
# /dev/ttysXXX is the result of the tty command in another Terminal window
sudo ttyecho -n /dev/ttysXXX pwd
And maybe ttyecho could be combined with netcat (or nc) or ncat (which is part of nmap) for communicating between different ttys?
For more information see:
Utility to Send Commands or Data to Other Terminals (tty/pts) -- (ttyecho)
create read/write environment using named pipes
I suspect this is not possible. AFAIK, without modifying something in kernel space, it's impossible to read the input from a tty (or pty) that is not the current tty. Even root can't do it. I spent some time looking into this and I was unable to find out how to do it, but I did find lots of sources claiming it was impossible. This appears to have been a design decision to increase security/privacy of users.
To answer your clarified question, a simple way is to use a FIFO (named pipe) for the job. On sending terminal:
mkfifo ./myfifo
read var
echo "var" > myfifo
On the recieving terminal:
read line < ./myfifo
To simply print an another xterm from your own, in recieving xterm:
$ tty
/dev/pts/2
In sending xterm:
$ echo howdy doody > /dev/pts/2
Or from a script in the sending xterm, redirecting stdin as you asked:
$ cat > /dev/pts/2
You have to chmod the permissions to write to /dev/pts/2 if your doing this across users.
You cannot capture whats printed this way on the recieving terminal. There is no builtin redirection method to capture the input from another terminal.
If you want an automated way for the sending xterm to find out the character device of the receiving one, that could be answered several ways depending on what kind of interprocess communication you want to use. A simple hack would be for the receiver to do tty > file1 and the sender to do echo whatever > $(cat file1).
If you want to try and direct this from the receiver instead of the sender, again you have an interprocess communication problem that can be solved in several ways.
it is simple
you just need understand
ls -ls /dev/pts
you will see
0 1 2 3 4
suppose you open several
now use one NOT 4
and type
cat < /dev/pts/4
or
exec < cat /dev/pts/4
and type something in 4 th one
you now know what happens

Resources