Save and share an entire login session.
How many times have you either struggled with or tried to troubleshoot another user through a thorny problem? Didn't you wish you had another set of eyes behind you so you could simply type your command set, point at the troublesome output, and say, "That's the problem." Well, if you can't bring another user to your output, you can still share that real-time output using an interactive shell.
1.12.1 Recording All Shell Input and Output
There are actually several ways to share what is happening on your screen. Let's start by recording all of your input and output to a file. Then we'll see how we can also allow another user to view that output from another terminal.
Your BSD system comes with the script command which, not surprisingly, allows you to script your session. This command is extremely simple to use. Simply type script:
% script Script started, output file is typescript
By default, script will create an output file named typescript in your current directory. If you prefer, you can specify a more descriptive name for your script file:
% script configure.firewall.nov.11.2003 Script started, output file is configure.firewall.nov.11.2003
Regardless of how you invoke the command, a new shell will be created. This means that you will see the MOTD and possibly a fortune, and your .cshrc will be reread.
You can now carry on as usual and all input and output will be written to your script file. When you are finished, simply press Ctrl-d. You will see this message:
Script done, output file is configure.firewall.nov.11.2003
If you've ended a script and decide later to append some more work to a previous session, remember the -a (append) switch:
% script -a configure.firewall.nov.11.2003
This will append your current scripting session to the named file.
I find script extremely useful, especially when I'm learning how to configure something for the first time. I can easily create a written record of which commands I used, which commands were successful, and which commands caused which error messages. It also comes in handy when I need to send an error message to a mailing list or a program's maintainer. I can simply copy or attach my script file into an email.
1.12.2 Cleaning Up script Files
The script utility is a very quick and dirty way to record a session, and it does have its limitations. One of its biggest is that it records everything, including escape characters. For example, here is the first line from one of my script files:
[1mdru@~ [m: cd /s [K/ysr/ [K [K [K [K [Kusr/ports/security/sn o rt
It's a bit hard to tell, but this is what script was recording:
This isn't really script's fault; it's ugly for several reasons. One, my customized prompt contains control characters. Those display as [1m and [m around my username. Second, I had problems typing that day. Instead of /usr, I typed /s and had to backspace a character. Then I typed /ysr and had to backspace three characters. Finally, I used tab completion. You can see that I tried to tab at sn but received a beep; I then tried to tab at sno and had my input completed to snort.
Granted, if I had first used the file utility on my script file, I would have received a warning about this behavior:
% file configure.firewall.nov.11.2003 configure.firewall.nov.11.2003: ASCII English text, with CRLF, CR, LF line terminators, with escape sequences
All is not lost, though. This command will get rid of most of the garbage characters:
% more configure.firewall.nov.11.2003 | \ col -b > configure.firewall.nov.11.2003.clean
col is an interesting little utility. It silently filters out what it doesn't understand. Here's an example where this actually works to our advantage. col doesn't understand control characters and escape sequences, which is exactly what we wish to get rid of. Including -b also asks col to remove backspaces.
The result is much more readable:
1mdlavigne6@~m: cd /usr/ports/security/snort % file configure.firewall.nov.11.2003.clean configure.firewall.nov.11.2003.clean: ASCII English text
I've found that using an editor during a script session also produces very messy output into my script file. The preceding col -b command will clean up most of the mess, but I still won't have a very good idea of exactly what I typed while I was in that editor. For this reason, I use the echo command to send little comments to myself:
% echo # once you open up /etc/rc.conf % echo # change this line: linux_enable="NO" % echo # to this: linux_enable="YES" % echo # and add this line: sshd_enable="YES"
1.12.3 Recording an Interactive Shell Session
Let's look at an alternate way of recording a session. This time I'll use the -i (or interactive) switch of my shell:
% csh -i | & tee test_session.nov.12.2003
In that command, I used -i to start an interactive tcsh shell. I then piped (|) both stdout and stderr (&) to the tee command. If you've ever looked at physical pipe plumbing, you'll recognize the job of a "tee" in a pipe: whatever is flowing will start going in both directions when it hits the "tee." In my case, all stdout and stderr generated by my shell will flow to both my monitor and to the test_session.nov.12.2003 file. When I'm finished recording my session, I can type Ctrl-c, Ctrl-d, or exit to quit.
Like the previous script command, an interactive csh shell will present me with a new shell. However, this method does not record escape characters, meaning I won't need to use the col -b command to clean up the resulting file.
But if I try to use vi during my session, the shell will refuse to open the editor and will instead present me with this interesting error message:
ex/vi: Vi's standard input and output must be a terminal.
If I try to use ee, it will open, but none of the commands will work. pico works nicely but still throws garbage into the session file. So, if I need to use an editor during my session, I'll still echo some comments to myself so I can remember what I did while I was in there.
Appending works almost exactly like it does for script, again with the -a (append) switch:
% csh -i | & tee -a test_session.nov.12.2003
1.12.4 Letting Other People Watch Your Live Shell Sessions
Regardless of which method you choose to record a session, another user can watch your session as it occurs. In order for this to work, that user must:
For example, I've created a test account on my system and configured sshd. I'll now see if I can ssh into my system as the user test and watch the results of dru's test_session.nov.12.2003.
% ssh -l test 192.168.248.4 Password: %
Once I successfully log in, my customized prompt indicates I'm the test user. I can now use the tail command to watch what is happening in dru's session:
% tail -f ~dru/test_session.nov.12.2003
My prompt will appear to change to indicate I am the user dru. However, I'm not. I'm simply viewing dru's session. In fact, I can see everything that the user dru is seeing on her terminal. This includes all of her input, output, and any error messages she is receiving.
While tail is running, I won't be able to use my prompt. If I try typing anything, nothing will happen. I also can't interact with the user or change what is happening on her terminal. However, I do have a bird's eye view of what that user is experiencing on her terminal. When I'm ready to return to my own prompt, which will also end my view of the session, I simply need to press Ctrl-c.
1.12.5 See Also