>(tee -ia $SDIR/bash.log) fi It only works in bash, but when the shel" /> >(tee -ia $SDIR/bash.log) fi It only works in bash, but when the shel" /> >(tee -ia $SDIR/bash.log) fi It only works in bash, but when the shel"/>

Conditionally bypass a command based on type of shell bash vs ksh

71 Views Asked by At

I have this line in script.

if [ "$(ps -p $$ -o comm=)" = "bash" ]; then
    exec 1> >(tee -ia $SDIR/bash.log)
fi

It only works in bash, but when the shell is not bash, that is in ksh, I get this error

./col[2]: 0403-057 Syntax error at line 3 : `>' is not expected.

Any way to make the script generic? I want basically to create a output log file of the script if it runs in bash/ksh and also display on screen.

Tried

if [ "$(ps -p $$ -o comm=)" = "bash" ]; then
    exec 1> >(tee -ia $SDIR/bash.log)
fi

but does not work.

3

There are 3 best solutions below

0
John Bollinger On BEST ANSWER

Any way to make the script generic?

You can get output to both screen and log in both shells, which I guess is even more generic than you asked. Use a compound command ({ ... }) to wrap everything whose output you want to capture in the log, and pipe its output into tee.

Be aware that the use of a pipe will force the compound command into a subshell, which is not analogous to your version. That could conceivably have unwanted side effects, but I'm inclined to guess that that's unlikely in your particular case.

Example:

SDIR=/foo/bar

{
    echo 'Hello, World!'
} | tee -ia "${SDIR}/bash.log"
3
KamilCuk On

Simple way is to check the existence of $BASH_VERSION to detect bash. This is not foolproof, but usually what you want to do.

if [ -n "$BASH_VERSION" ]; then

Also take a look at OpenSUSE distribution /etc/profile implementation, which uses /proc/self/exe to determine the executable name https://github.com/openSUSE/aaa_base/blob/master/files/etc/profile#L14 .

2
William Pursell On

Rather than trying to restrict functionality to certain shells, just write a generic script. Note that if you do decide to restrict functionality, don't restrict to certain shells. Instead, test whether the current shell supports the functionality and decide based on that. Test functionality, not platform. It's not terribly pretty, but you can get the functionality you want with a fairly generic script. eg:

#!/bin/sh
trap 'rm -f $t' 0 # cleanup the temporary file on exit
t=$(mktemp)       # create the temp file (will be a fifo) 
rm $t; mkfifo $t  # convert the tmpfile to a fifo
tee -ia $SDIR/bash.log < $t & # spawn tee to read the fifo 
exec > $t        # redirect all output to the fifo
echo foo