Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'd like my script to output to stdout unless it gets a filename as an argument. An obvious way is like so:

if [ -e "$1" ]; then
  command_with_output >$1
else
  command_with_output
fi

It's pretty ugly and has repetition, so I'd like a more consice way to do it.

I tried the following, but it doesn't work.

[ -e "$1" ] && outfile=$1 || outfile='&1'
command_with_output >$outfile

Edit: This doesn't change the relevancy of the answers, but I realized after I made the question that touch "$1" && outfile=$1 is really what I need instead of [ -e "$1" ] && outfile=$1 since the file may not already exist, and I want to make sure I can write to it or create it, not just that it exists. I'm not changing the question because it would put the answers out of sync.

share|improve this question
    
I wouldn't normally do that. For users of the script, is it really a gain being able to call your script ./yourscript.sh filename instead of ./yourscript.sh > filename? I'd say no, or at least the marginal benefit is normally outweighed by the additional complexity in the interface. The exception to the rule is programs with non-human-readable output (Say, image converter, or wget). Those usually provide an -o filename switch where filename can be - to say you really want that crap on stdout. –  Jo So Jul 2 '12 at 18:39

3 Answers 3

Another way is to use $1 as the filename if it was passed, and /dev/stdout otherwise (which is a symbolic link to /proc/self/fd/1 under Linux, and a device node with the same meaning on many other unix variants). E.g. put this at the top of the script:

if [ -e "$1" ]; then
    filename=$1
else
    filename=/dev/stdout
fi

And then redirect the output of every command to $filename

share|improve this answer
    
I prefer the exec method because you can fail early if the output file is not writable. –  Gilles Jul 2 '12 at 21:52

If it doesn't take any but file parameters, this will work too:

command_with_output > ${1:-/dev/stdout}

edit: Or better yet, since you probably care about errors too:

command_with_output &> ${1:-/dev/stdout}
share|improve this answer
    
That's the same as @michael-mrozek's except it doesn't check for the existance of $1 before using it. Which is okay; what I really want is touch $1 &&... instead, to make sure I can create/write to the file. –  Shawn J. Goff Jul 2 '12 at 16:07
    
it's more concise. :) –  lynxlynxlynx Jul 2 '12 at 16:19

exec can be used to redirect the current script's stdout to another file.

[ -e "$1" ] && exec > $1
command_with_output
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.