Please note that LinuxExchange will be shutting down on December 31st, 2016. Visit this thread for additional information and to provide feedback.

Hi all,

Is there an efficient way to log all the commands being executed from a shell script?

For example if I have in my script:

  firstLoop=$(losetup -f)
  losetup $firstLoop $my_vol

is there a way to automatically log the command (may be by 'set'ting some options) being executed and the result from the command into a log file. Currently I am performing it by passing the command to a shell function, log the command+arguments into a log file and execute the command from the command line by 'tee'ing it into the log file. I have given the function below:

ExecuteCommand(){
  retVal=0
  # LogMessage is  another function that writes the given string into the log file
  LogMessage "-------------- Command Start ------------------------------------------------"
  LogMessage "Command = $*"
  # Execute the command so that the output(and error) is redirected both to the stdout and
  # the logfile
  "$@" 2>&1 | tee -a ${logFile}
  for curr_ret_status in ${PIPESTATUS[@]}
  do
    retVal=${curr_ret_status}
    # Break the loop if it is not a success
    [[ $retVal -ne 0 ]] && break
  done
  LogMessage "Return code is ${retVal}"
  LogMessage "-------------- Command End --------------------------------------------------"
  return $retVal
}

With this approach my example script given above will become:

  firstLoop=$(ExecuteCommand losetup -f)
  ExecuteCommand losetup $firstLoop $my_vol

Do I have to perform what I want only by this way? Or is there a standard efficient way to do this?

Please let me know if you need more information in this regard.

Thanks

asked 02 Aug '11, 05:55

Guna's gravatar image

Guna
11112
accept rate: 0%




You could utilize the history. Wrap the following into a function:

RETVAL=$? & echo "!-1 Returned: $RETVAL" >> logfile

Calling a command could be simplified as the following, then:

random_command
log_function_call

Something is flawed in the above example, because the logged return value is wrong, but this should get us started. It's not a solution for your wanted automation, but should simplify your code at least.

link

answered 02 Aug '11, 07:11

Jazz's gravatar image

Jazz ♦
7811312
accept rate: 33%

Hi Jazz,

Thanks for taking time to answer. Can you please explain a bit more in detail? I am not a regular scripting guy.

Thanks

(03 Aug '11, 05:00) Guna

The most complicated part of my example is possibly the use of "$?" and "!-1". $? retrieves the exit status of the last command, and "!-n" is replaced by the command n-lines back. By putting "!-n" into echo, I am able to use the history to write the executed command into a logfile.

Could you be more specific about your goal? It seems to me that you want to simplify your logging script. Because of this, I recommend using a combination of "history" (see the provided link), for retrieving the command that was executed, and I/O redirection (examples 16-2 and 16-3: http://www.faqs.org/docs/abs/HTML/io-redirection.html ).

(03 Aug '11, 07:03) Jazz ♦

Thanks Jazz,

The pages you provided are very helpful. I have to go alter things slightly with great care (I have a quite big system to implement). I shall keep you posted with the outcome.

Thanks

(04 Aug '11, 04:15) Guna

The "script" command will capture everything written to the screen. To capture interactive output just say "script" and it'll tell you where the session log is being stored (usually in the /tmp dir) or you can specify the name thus:

   script yourSessionLogFileNameHere

...and if you want to capture the output of a specific command then you can specify that as well:

   script -c yourCommandHere yourSessionLogFileNameHere

...and if you want to capture the output of several commands then mention them in a shell script and specify that, instead:

   script -c yourShellScriptHere yourSessionLogFileNameHere

Note that the output will contain everything emitted during your session so you may have to filter out some stuff like escape, backspace and carriageReturn characters that you might not have expected to find. Also, be aware that the script command spawns a new instance of your shell to do its work so if you're running interactively you'll need to exit that instance of the shell before you can process the log file. And it's generally a bad idea to cat the log file while the script session is live as that just causes it to be endlessly added to its own log file... ;->

link

answered 08 Sep '11, 08:22

mod's gravatar image

mod
393
accept rate: 0%

edited 08 Sep '11, 17:24

What I'd like to do is to be able to log this installation script as it runs, so what would be the best way to do that? (There are some interactive spots in it too.)

http://sourceforge.net/projects/ubuntune/files/UbunTUNE/latest-version/

(08 Sep '11, 15:14) Ron ♦

If you copy that Ubuntune installation script into /tmp/Ubuntune.sh and ensure it's executable, thus:

   chmod a+x /tmp/Ubuntune.sh

...then the approach using the "script" command should work fine, thus:

   script -c /tmp/Ubuntune.sh /tmp/Ubuntune.sessionLog
link

answered 08 Sep '11, 17:23

mod's gravatar image

mod
393
accept rate: 0%

That didn't work. All it cpatured was me entering in the sudo line so it logged [sudo] password for username:

(08 Sep '11, 17:43) Ron ♦

I've never run that Ubuntune script so I don't know what you're referring to when you mention specific problems with its execution (like your sudo troubles) but since the "script" command basically captures all traffic at the lowest PTY level I've rarely seen anything fail with it. Does Ubuntune work for you without the "script" command?

A shot-in-the-dark here - maybe try this:

   sudo script -c /tmp/Ubuntune.sh /tmp/Ubuntune.sessionLog

...effectively running that Ubuntune script with root privileges, which may or may not be what you want.

link

answered 08 Sep '11, 17:57

mod's gravatar image

mod
393
accept rate: 0%

Yes, it works without the script command if you just run sudo ./ubuntune.sh

(09 Sep '11, 10:27) Ron ♦

Hmmmmm. How about this: start a new bash session whose output is being captured via the "script" command and then invoke your Ubuntune thing from that instance of the shell, thus:

   # Start new interactive instance of your shell
   script /tmp/Ubuntune.sessionLog

...then from that new shell instance, launch your Ubuntune thing. After it completes, you'll need to exit that instance of the shell so that the logfile is fully written out, after which you should be able to find the results in /tmp/Ubuntune.sessionLog

Are you the author of that Ubuntune thing?

link

answered 09 Sep '11, 11:06

mod's gravatar image

mod
393
accept rate: 0%

I am the author of Ubuntune, yes. :) It's a script for modifying Ubuntu by adding some apps, removing others, setting up some configurations, etc.

Ideally, I'd like to have code in the very beginning of the script which automates the logging and outputs a text file to the desktop.

The sudo command before the rest still produced the same results.

(09 Sep '11, 16:25) Ron ♦

Dang! this one has been nagging at me - I've used the script command throughout my career and it's just been completely reliable, so I conclude that it's something about your particular situation that's b0rken. You haven't supplied much detail about the specific failures you're seeing but it really shouldn't matter - as I said previously, the script command operates at a very low level (the PTY) and should work in pretty much any situation the normal user might concoct. Another shot-in-the-dark: maybe something is emitting a byte sequence that's wedging your terminal emulator, so maybe if you execute the commands in question from a console terminal you could get past that point. Try this:

   sudo chvt 1

...and then login as root, then start a shell session whose output is being captured, thus:

   script /tmp/Ubuntune.sessionLog

...and then launch your Ubuntune thing from there, remembering to exit that shell session when it's done so that the script command will flush the logfile. You might also experiment with using the -f option to the script command to force logfile updates after every write; maybe the last thing you see will be a clue as to where things got wedged up...

Assuming your X server is using Virtual Terminal 7 you can get back to X thus:

   chvt 7
link

answered 12 Sep '11, 13:13

mod's gravatar image

mod
393
accept rate: 0%

Besides using "script" why don't you add -x on your first line of your script. This will show every step of the script when execute.

link

answered 19 Oct '11, 09:26

eddiez's gravatar image

eddiez
11
accept rate: 0%

To follow mod's example, I used the script command with a sample "echo" command, and it seems to be working fine for me. Here is what I used : script -c ./1.sh -a 1.log

Worked like a dream. Maybe it breaks for some command being issued in the Ubuntune thing

link

answered 21 Oct '11, 15:16

jawsnnn's gravatar image

jawsnnn
1
accept rate: 0%

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "Title")
  • image?![alt text](/path/img.jpg "Title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×16
×8

Asked: 02 Aug '11, 05:55

Seen: 15,628 times

Last updated: 21 Oct '11, 15:16

powered by OSQA