When I try to get file list with some rule.
[[email protected]:~]
$ for x in ./*;do echo $x; done;
/home/mariolu/out_protocol
/home/mariolu/proto
/home/mariolu/proto2
/home/mariolu/protocol_build.3.6.1.sh
/home/mariolu/protocol_build.3.6.sh
/home/mariolu/replace_pb_lite_runtime.sh
It works.
When I list only .sh
files. It also works.
[[email protected]:~]
$ for x in ./*.sh;do echo $x; done;
/home/mariolu/protocol_build.3.6.1.sh
/home/mariolu/protocol_build.3.6.sh
/home/mariolu/replace_pb_lite_runtime.sh
But I try to list only .proto
files. It does not work properly.
[[email protected]:~]
$ for x in ./*.proto;do echo $x; done;
*.proto
Bash treats $x
like string *.proto
. But here intention is that $x
is a empty list and code breaks from "for loop".
I frequently use shopt
in scripts, but when you don't want to, you should explicitly test the result.
You can test for the glob string itself -
for x in *.proto;
do [[ "$x" == '*.proto' ]] && continue
echo $x
done
but '*.proto' is actually a valid filename, so it's possible it could get created and this would skip it. That might be a bug or a feature, depending on your needs.
Another approach is to test if the filename actually exists.
for x in ./*.proto;
do [[ -e "$x" ]] && echo $x
done
This will include any file literally named *.proto
if it exists...