I am adding a script (command?) for a modified head
command to my ~/.bashrc. It handles inputs as expected, both when manually entered, when derived from globbing, and when provided by stdin. However, if I forget to provide an argument to headj
, my terminal hangs and can't be recovered with Ctrl-C.
Here is my code (with some calls to echo
for debugging purposes:
headj(){
echo "script makes it this far without arguments"
IFS=" " read -r -a input <<< "${@:-$(</dev/stdin)}"
echo "but but crashes before getting here"
#
for i in ${input[@]}; do
echo -e "███████████████████████████████████████████████████████████████████████████████"
echo -e "headj $i start"
head -50 "$i"
done
}
And here is how it behaves:
$ headj list1
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b
$ headj list*
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b
███████████████████████████████████████████████████████████████████████████████
headj list2 start
c
d
$ ls -1 li* | headj
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b
███████████████████████████████████████████████████████████████████████████████
headj list2 start
c
d
$ headj
script makes it this far without arguments
and that's where it hangs.
I've tried reading the inputs using input=( ${@:-$(</dev/stdin)} )
but get the same error. Adding this code at the beginning of the script handles the error.
if [ -z ${*:+x} ]; then
echo "headj requires at least one argument"
return
fi
Is there a better way to do this? Also, is there a keyword I should be searching for this type of problem?
while :; do; case $1 in; -a|--arg) OPTARG=$2 ... blah blah blah... ; shift;; esac; shift; done
, but that seems overkills in this case, especially since all arguments toheadj
will be treated the same andheadj
doesn't take any optional arguments."$@"
it contains all arguments passed to script (and you can check for$1
or even set default${1:-default}
)/dev/stdin
is needed to accept information from pipes. Also, can you be a little more specific in your suggestion regarding"$0"? I just tried a number of different variations using
"$0"` or$0
; not all of them worked for my simple test and I'm pretty sure many would fail with edge cases../script.sh ./dir1 "./dir 2"
we could just use it straight for examplefind "$@"
(will work with spaces in folder names). so ${@:-$(</dev/stdin)} will use positional parameters, or (as default) read from stdin? then this is probably the reason because you didn't pipe anything