Find the answer to your Linux question:
Results 1 to 8 of 8
I have a short script for which I want it to either output to the terminal it's being run in ("standard out") or to a log file depending on the ...
  1. #1
    Just Joined!
    Join Date
    Mar 2009
    Posts
    4

    Standard Output for script

    I have a short script for which I want it to either output to the terminal it's being run in ("standard out") or to a log file depending on the condition of a flag. If I call "report.sh" it should run (and output) in the terminal, if I call "report.sh -q" it should send its output to log files.

    At the moment I am using getopts (Linux.com :: Parsing arguments for your shell script) to parse the flags so that if -q is specified the variable quiet=1 and I have a conditional statement for if [ "quiet" ] then OUT=$logfile, else OUT=$standardoutput. For each subsequent command I then direct its output towards $OUT.

    My problem is that I don't know what to set $OUT to for when I want it "sent" to standard out, and also something is screaming at me that there should be a simpler way to do this. My script as it stands is below, any suggestions?

    Code:
    #!/bin/bash
    #
    # This file generates reports on the status
    # of running jobs on various servers
    #
    
    # Location of log files
    OLD=$HOME/tmp/jobStatus.old
    NEW=$HOME/tmp/jobStatus.new
    
    # Parse arguments
    quiet=
    while getopts 'q' OPTION
    do
       case $OPTION in
       q)  quiet=1
                   ;;
       ?)  echo    "Usage: $(basename $0) [-q for quiet output)]" >&2
                   exit 2
                   ;;
       esac
    done
    shift $(($OPTIND - 1))
    
    # If quiet, setup log file output
    if [ "quiet" ]; then 
       if [ -a $OLD ]; then rm $OLD ; fi
       if [ -a $NEW ]; then mv $NEW $OLD ; fi
       OUT=$NEW
    else
       OUT="??? - standard out"
    fi
    
    # Main body of script
    user=username
    servers=(server01 server02 server03)
    
    date +%d/%m/%y\ %R > $OUT
    for i in ${servers[@]}; do
      ssh -l $user ${i} "~/bin/running -c" >> $OUT
    done

  2. #2
    Just Joined!
    Join Date
    Oct 2004
    Posts
    62
    Hi,
    I'm not an expert, but after many years, you learn something...
    The outputs are two: the standard one (the screen) and the error output (normally it too using the screen).
    The 1st is "automatically" directed to screen and you need no action except printing or echoing (if you use bash) the data you want.
    The output of any program that accesses the screen can be redirected to a file and visualized
    by a text or a graphic editor by the well known
    Code:
    executable (options) command_object > file_capturing_output
    for ex. ls -1 MyDir > myDir_FileList.txt
    As you see you don't have to modify the source of the command ls (probably a c program)...
    The same thing is valid also for logging.

    The redirection captures also the error output. Such a thing is sometime annoying.
    For example try to use find outside of the home...
    In such a case I use the redirection of error to null...
    Code:
    find /usr -name "*xx*" 2>/dev/null
    In this way you don't see the annoying "access denied"...
    As a conclusion I would write a script with no options for output... you decide what you want
    by running with or without redirection to a file or a log file.
    Bye

  3. #3
    Just Joined!
    Join Date
    Mar 2009
    Posts
    4
    Thanks fiomba, I believe I understand what you are saying but I shall try to rephrase my question in response...

    I would like my script either to output to the screen or to a log file. From what you are saying I would do this simply by calling the script by it's name or by appending "> logfile" after calling it which I understand. The complication is the management of the logfiles.

    If I want the script to output to log files the idea is to maintain two files - the current output "jobStatus.new" and the previous output "jobStatus.old" which I will then subsequently examine with diff to determine any changes (I'm learning a bit of awk at the moment as well!). To do this I currently use the log management section to shuffle the log files, however I don't need to do this if I output to the screen.

    I guess I could do something like...

    Code:
    if [ "quiet" ]; then
       date +%d/%m/%y\ %R > $OUT
       for i in ${servers[@]}; do
           ssh -l $user ${i} "~/bin/running -c" >> $OUT
       done
    else
       date +%d/%m/%y\ %R
       for i in ${servers[@]}; do
          ssh -l $user ${i} "~/bin/running -c"
       done
    fi
    ...but it would be ideal if I could use $OUT for either screen or file output.

  4. #4
    Linux Enthusiast
    Join Date
    Aug 2006
    Location
    Portsmouth, UK
    Posts
    539
    RHCE #100-015-395
    Please don't PM me with questions as no reply may offend, that's what the forums are for.

  5. #5
    Linux Newbie
    Join Date
    Mar 2009
    Posts
    228
    The "standard out" is a device called /dev/stdout. So assign your variable to it:

    Code:
    OUT=/dev/stdout

  6. #6
    Just Joined!
    Join Date
    Mar 2009
    Posts
    4
    Excellent, that's what I was looking for lomcevak - knew it had to be something simple. I've already tweaked the file now though however and gone with earlier suggestions of just sending output to file from calling the script.

    Thanks all the same.

  7. #7
    Linux Enthusiast
    Join Date
    Aug 2006
    Location
    Portsmouth, UK
    Posts
    539
    Glad you've found what you wanted

    I must admit that I do like colucix's solution from the earlier posting
    Code:
    #!/bin/bash
    logfile=$$.log
    exec > $logfile 2>&1
    As it gives you an easy way to output to either a log file, stdout or both depending on options passed to your script.
    RHCE #100-015-395
    Please don't PM me with questions as no reply may offend, that's what the forums are for.

  8. #8
    Linux Newbie
    Join Date
    Mar 2009
    Posts
    228
    I like colucix's solution as well. Problem is I don't fully understand how the exec command works. I did figure out how to turn it off in the script if you wish as follows:

    Code:
    logfile=$$.log
    exec 3>&1
    exec > $logfile 2>&1
    echo Hi1
    exec 1>&3 3>&-
    echo Hi2

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...