Here is a script I have written for logging in bash called echoline.sh
. When called with the flag -e
, echoline prints to stderr instead of stdout. With the flag -o
, the script writes to a given file.
<code>#!/bin/bash
# ---------- echoline.sh ----------
to_stderr=false
### get input
set -f # stops * being expanded
cml_args="$*" ### flags passed via pipe are caught here
if test ! -t 0; then
read -r pipe_args # pipe
fi
### parse input
while getopts ":seco:" arg; do
case "${arg}" in
e)
cml_args=${cml_args//"-e"/}
;;
o)
outfile=$OPTARG
cml_args=${cml_args//"-o"/}
cml_args=${cml_args//"$outfile"/}
;;
*)
;;
esac
done
if [[ -z $outfile ]]; then
echo "Error in echoline.sh: outfile not given" 1>&2
exit 1
fi
### format data
if [[ -n "$pipe_args" ]]; then
indata="$pipe_args"
else
indata="$cml_args"
fi
### trim extra whitespace
indata=$( echo "$indata" | tr -s " " )
indata="${indata#" "}"
IFS='$'; arrIN=("$indata"); unset IFS;
### output to console
printable=$( IFS=$'n'; echo "${indata[*]}" )
if [[ $to_stderr == false ]]; then
echo "$printable"
else
echo "$printable" 1>&2
fi
### output to file
for (( x=0; x<${#arrIN[@]}; x++))
do
outdata=$( echo "${arrIN[x]}" | ./formatter.py | tr -d """ | tr -d "'" )
echo -e "$(date '+%H:%M:%S-%Z') > $outdata" >> "$outfile"
done
</code>
<code>#!/bin/bash
# ---------- echoline.sh ----------
to_stderr=false
### get input
set -f # stops * being expanded
cml_args="$*" ### flags passed via pipe are caught here
if test ! -t 0; then
read -r pipe_args # pipe
fi
### parse input
while getopts ":seco:" arg; do
case "${arg}" in
e)
cml_args=${cml_args//"-e"/}
;;
o)
outfile=$OPTARG
cml_args=${cml_args//"-o"/}
cml_args=${cml_args//"$outfile"/}
;;
*)
;;
esac
done
if [[ -z $outfile ]]; then
echo "Error in echoline.sh: outfile not given" 1>&2
exit 1
fi
### format data
if [[ -n "$pipe_args" ]]; then
indata="$pipe_args"
else
indata="$cml_args"
fi
### trim extra whitespace
indata=$( echo "$indata" | tr -s " " )
indata="${indata#" "}"
IFS='$'; arrIN=("$indata"); unset IFS;
### output to console
printable=$( IFS=$'n'; echo "${indata[*]}" )
if [[ $to_stderr == false ]]; then
echo "$printable"
else
echo "$printable" 1>&2
fi
### output to file
for (( x=0; x<${#arrIN[@]}; x++))
do
outdata=$( echo "${arrIN[x]}" | ./formatter.py | tr -d """ | tr -d "'" )
echo -e "$(date '+%H:%M:%S-%Z') > $outdata" >> "$outfile"
done
</code>
#!/bin/bash
# ---------- echoline.sh ----------
to_stderr=false
### get input
set -f # stops * being expanded
cml_args="$*" ### flags passed via pipe are caught here
if test ! -t 0; then
read -r pipe_args # pipe
fi
### parse input
while getopts ":seco:" arg; do
case "${arg}" in
e)
cml_args=${cml_args//"-e"/}
;;
o)
outfile=$OPTARG
cml_args=${cml_args//"-o"/}
cml_args=${cml_args//"$outfile"/}
;;
*)
;;
esac
done
if [[ -z $outfile ]]; then
echo "Error in echoline.sh: outfile not given" 1>&2
exit 1
fi
### format data
if [[ -n "$pipe_args" ]]; then
indata="$pipe_args"
else
indata="$cml_args"
fi
### trim extra whitespace
indata=$( echo "$indata" | tr -s " " )
indata="${indata#" "}"
IFS='$'; arrIN=("$indata"); unset IFS;
### output to console
printable=$( IFS=$'n'; echo "${indata[*]}" )
if [[ $to_stderr == false ]]; then
echo "$printable"
else
echo "$printable" 1>&2
fi
### output to file
for (( x=0; x<${#arrIN[@]}; x++))
do
outdata=$( echo "${arrIN[x]}" | ./formatter.py | tr -d """ | tr -d "'" )
echo -e "$(date '+%H:%M:%S-%Z') > $outdata" >> "$outfile"
done
However, I am having an issue where if I have a script that uses echoline, in this case get_serial_number.sh
, and that script is called via command substitution by another script, in this case first.sh
, the -e flag passed to echoline is not picked up and prints to stdout instead. However, the script writes to the file just fine.
<code>#!/bin/bash
# ---------- first.sh ----------
example_serial=$(./get_serial_number.sh)
echo "example_serial = $example_serial"
</code>
<code>#!/bin/bash
# ---------- first.sh ----------
example_serial=$(./get_serial_number.sh)
echo "example_serial = $example_serial"
</code>
#!/bin/bash
# ---------- first.sh ----------
example_serial=$(./get_serial_number.sh)
echo "example_serial = $example_serial"
<code>#!/bin/bash
# ---------- get_serial_number.sh ----------
echoLine() {
here=$(pwd)
./echoline.sh -o "$here/test.log" "$@"
}
main() {
echoLine -e "This is supposed to write to stderr, but actually writes to stdout"
echo "This is supposed to write to stdout and does."
}
main
</code>
<code>#!/bin/bash
# ---------- get_serial_number.sh ----------
echoLine() {
here=$(pwd)
./echoline.sh -o "$here/test.log" "$@"
}
main() {
echoLine -e "This is supposed to write to stderr, but actually writes to stdout"
echo "This is supposed to write to stdout and does."
}
main
</code>
#!/bin/bash
# ---------- get_serial_number.sh ----------
echoLine() {
here=$(pwd)
./echoline.sh -o "$here/test.log" "$@"
}
main() {
echoLine -e "This is supposed to write to stderr, but actually writes to stdout"
echo "This is supposed to write to stdout and does."
}
main
Running first.sh
gives this output:
<code>[root@DESKTOP-A8HSSI8 test]# ./first.sh
I can write to stderr here just fine!
example_serial = This is supposed to write to stderr, but actually writes to stdout
This is supposed to write to stdout and does.
</code>
<code>[root@DESKTOP-A8HSSI8 test]# ./first.sh
I can write to stderr here just fine!
example_serial = This is supposed to write to stderr, but actually writes to stdout
This is supposed to write to stdout and does.
</code>
[root@DESKTOP-A8HSSI8 test]# ./first.sh
I can write to stderr here just fine!
example_serial = This is supposed to write to stderr, but actually writes to stdout
This is supposed to write to stdout and does.