# std. err and std. output redirect to a file



## cgjoker (Aug 13, 2003)

When I run a unix script using telnet, messages (including but not limited to std. errors) are displayed on my screen.

I would like to basically capture everything that appears on the screen, which is the commands in the script themselves and any errors, and place them all into a file.

Ive tried several variations of 1>&2 etc., and I can't seem to get it to work.

I know that by typing

cmd 2> file 

it places the errors of that command into my file, but it won't capture the actual execution of the command. 

anyone have any ideas? 

thx.


----------



## codejockey (Feb 11, 2002)

Have a look at the script command (man script). This command captures everything you do and the results until you tell it to stop. So, for example, if you wanted to record all of the terminal input and output, you might use the command:

script session.out

which will capture everything you do at the terminal in the file session.out. You stop recording by giving the command: exit. 

Hope this helps.


----------



## cgjoker (Aug 13, 2003)

Hi thanks for the reply.

I have tried the script command but my unix program cuts out once it hits the script command. None of the commands that follow the script parameter are executed.

Heres my program:

script terminal_output.out

cd /Ad_Hoc

rm file_a.dat 

exit;


----------



## codejockey (Feb 11, 2002)

OK, I'm confused (happens all the time, nothing to worry about ... )

When you say that none of "the commands that follow the script parameter are executed" do you mean (for example) that the command cd /Ad_Hoc doesn't work (i.e., you don't change directories to /Ad_Hoc)? Or do you mean that the command isn't recorded in the logfile terminal_output.out? 

Additional info appreciated.


----------



## cgjoker (Aug 13, 2003)

neither the commands nor the output works.

the program just terminates after I launch it and it hits the script command.


----------



## codejockey (Feb 11, 2002)

I may have misunderstood your original post (sorry). Now I'm thnking that you are writing some sort of script that uses telnet to connect to a machine (within the script) and you wish to capture all output from the telnet session with that machine. Is this what you have in mind?

Looking at your example, it seems you might have something more like this in mind:

script script.log << EOF > script.out 2>&1
pwd
ps -ef
df -k
cd /tmp
ls
cd -
pwd
EOF

If you save this script in a file and execute it, you should collect everything in the script.out file. The script.log file will have much of the same information, but it will be difficult to read, since it will contain the raw characters used by the terminal (e.g., you may see ^M for carriage return, etc.).

Hope this helps.


----------



## cgjoker (Aug 13, 2003)

what you've suggested is in fact what im trying to do, which is capture whatever I would see in my telnet window into a log file resulting from me running a script on the telnet command line.

unfortunately though this is what comes out...

get window size: Not a typewriter


----------



## cgjoker (Aug 13, 2003)

here is something simple that im trying to do in a script that I would like to capture in a log file.

#!/bin/ksh

set -x

script script.out << EOF > /logs/script.log 2>&1

echo "this is a test"

EOF

exit;

i get the error i mentioned in my last reply.

?


----------



## codejockey (Feb 11, 2002)

The "not a typewriter" error (ENOTTY) usually means that you have tried to perform a terminal-related operation on an object that is not a terminal. I suspect this may be coming from the combination of your telnet session and redirected output. I'm (still) not sure how you're using telnet (in your script? to connect to another machine before running a script on the remote machine?) so any info appreciated; I'm not sure what you are describing when you refer to "running a script on the telnet command line." In case this might be helpful, I've included an example of using a shell script to automate a telnet session and capture the input/output (more or less -- see below). The script connects to a router, selects option 24 from the menu presented, then backs out using the escape character, and selects option 99 (exit). The router box is named "gateway". If the script is named telnet.in, I invoke it with the command:

ksh telnet.in > ksh.out

contents of telnet.in:
script -c 'telnet gateway' script.log << EOF
your-password-here
24
^[
99
^D
EOF

contents of ksh.out:
Script started, file is script.log
Script done, file is script.log
your-password-here
24
^[
99
^D
Trying 172.16.1.100...^M
Connected to gateway.^M
Escape character is '^]'.^M

Password: *********^M
^[7^[[1;24r^[8^[[;H^[[2J^[[5;6HGetting^[[5;14HStarted^[[6;8H1.^[[6;11HGeneral^[[6;19HSetup^[[7;8H2.^[[7;11HWAN^[[7;15HSetup^[[8;8H3.^[[8;11HLAN^[[8;15HSetup^[[9;8H4.^[[9;11HInternet^[[9;20HAccess^[[9;27HSetup^[[11;6HAdvanced^[[11;15HApplications^[[12;8H11.^[[12;12HRemote^[[12;19HNode^[[12;24HSetup^[[13;8H12.^[[13;12HStatic^[[13;19HRouting^[[13;27HSetup^[[14;8H15.^[[14;12HSUA^[[14;16HServer^[[14;23HSetup^[[5;43HAdvanced^[[5;52HManagement^[[6;45H21.^[[6;49HFilter^[[6;56HSet^[[6;60HConfiguration^[[8;45H23.^[[8;49HSystem^[[8;56HPassword^[[9;45H24.^[[9;49HSystem^[[9;56HMaintenance^[[16;45H99.^[[16;49HExit^[[21;27HEnter^[[21;33HMenu^[[21;38HSelection^[[21;48HNumber:^[[1;21H^[[3;31HRT314^[[3;37HMain^[[3;42HMenu^[[3;31H^[[21;56H24^[[21;56H^[[1;1H^[7^[[1;24r^[8^[[24;1H^[7^[[1;24r^[8^[[;H^[[2J^[[3;27HMenu^[[3;32H24^[[3;35H-^[[3;37HSystem^[[3;44HMaintenance^[[5;26H1.^[[5;30HSystem^[[5;37HStatus^[[6;26H2.^[[6;30HSystem^[[6;37HInformation^[[6;49Hand^[[6;53HConsole^[[6;61HPort^[[6;66HSpeed^[[7;26H3.^[[7;30HLog^[[7;34Hand^[[7;38HTrace^[[8;26H4.^[[8;30HDiagnostic^[[9;26H5.^[[9;30HBackup^[[9;37HConfiguration^[[10;26H6.^[[10;30HRestore^[[10;38HConfiguration^[[11;26H7.^[[11;30HUpload^[[11;37HFirmware^[[12;26H8.^[[12;30HCommand^[[12;38HInterpreter^[[12;50HMode^[[13;26H9.^[[13;30HCall^[[13;35HControl^[[15;26H11.^[[15;30HRemote^[[15;37HManagement^[[15;48HSetup^[[21;27HEnter^[[21;33HMenu^[[21;38HSelection^[[21;48HNumber:^[[21;56H^[[24;1HPlease^[[24;8Henter^[[24;14Ha^[[24;16Hnumber^[[21;56H9^[[24;1H^[[K^[[21;57H9^[[24;1HInvalid^[[24;9HEntry^[[21;58H^[[24;1HPle^[[24;5Hse ente^[[24;13H a^[[24;16Hnumber^[[21;56H^[[21;58H^[[24;1HInv^[[24;5Hlid Ent^[[24;13Hy ^[[24;16H ^[[21;58H

As you can see, the output is pretty garbled by the escape characters used to control interaction with the terminal. Unfortunately, the script command captures everything (escape sequences, control characters, you name it) which pretty much destroys the output. You can get some idea of what happens if you cat the output file, using the same terminal type you used during your telnet session, but that's not much help.

Hope this helps -- additional info appreciated.


----------



## cgjoker (Aug 13, 2003)

when I say telnet, I simply mean that I telnet to a server node on a AIX O/S RS/6000 server. Once logged on at the unix prompt I initate the script program.

So ...

telnet 10.x.x.x

(logon)

$> cd /scripts
$/scripts>ksh script.sh

(script runs)

Thats it in a nutshell. All the commands that are shown on the telnet window when I launch the script is what id like to capture in a log file.


----------



## codejockey (Feb 11, 2002)

Have you tried using the tee command with your telnet session? For example:

telnet 10.x.x.x | tee telnet.out 2>&1
... run commands on remote machine here

Note that you will still have to contend with all of the terminal control characters, but the output of your session should appear in telnet.out.

Hope this helps.


----------



## cgjoker (Aug 13, 2003)

that would work but the script will eventually be running in batch so there will be no user interaction which means I wouldn't be telnet'ing onto the server. The scipt would just be called and executed.

sorry to be a pain, and I truly appreciate your patience and taking the time to help me with this.


----------



## cgjoker (Aug 13, 2003)

guess I should elaborate on that last one....

so when its running in batch, I would like to have any errors that may be generated by the commands put into a file.

I know I could do something like:

command 2> <file>

but that would mean id need to put the '2>' for every command.

perhaps that would be the only way though.


----------



## codejockey (Feb 11, 2002)

You're more than welcome for any help I've provided (although I think it's pretty minimal at this point ).

When you run your script in batch, you can redirect all output (stdout, stderr) in one go when you invoke the script. As you mentioned, you can use something like:

scriptname > script.out 2>&1 &

which will run scriptname in the background and collect both stdout and stderr in the file script.out on the machine where scriptname was run. Even if your script includes multiple commands, the output from each will be collected in the file script.out, so you shouldn't need to add 2 > script.out to each command in your script. 

If that isn't what you have in mind (or doesn't work for you), you can also use the exec command within your script to save/redirect file descriptors globally (i.e, for all commands within the script).

Hope this helps.


----------



## cgjoker (Aug 13, 2003)

i think what you suggested will work perfectly.

i didn't even think of using it when invoking the script.

thanks for all your help.


----------

