Boolean Expressions in Shell Scripts
-
09-06-2019 - |
Question
What's the "right" way to do the following as a boolean expression?
for i in `ls $1/resources`; do
if [ $i != "database.db" ]
then
if [ $i != "tiles" ]
then
if [ $i != "map.pdf" ]
then
if [ $i != "map.png" ]
then
svn export -q $1/resources/$i ../MyProject/Resources/$i
...
Solution
The other solutions have a couple of common mistakes: http://www.pixelbeat.org/programming/shell_script_mistakes.html
for i in $(ls ...)
is redundant/problematic just do:for i in $1/resources*; do ...
[ $i != file1 -a $1 != file2 ]
This actually has 2 problems.a. The
$i
is not quoted, hence names with spaces will cause issuesb.
-a
is inefficient ifstat
ing files as it doesn't short circuit (I know the above is notstat
ing files).
So instead try:
for i in $1/resources/*; do
if [ "$i" != "database.db" ] &&
[ "$i" != "tiles" ] &&
[ "$i" != "map.pdf" ] &&
[ "$i" != "map.png" ]; then
svn export -q "$i" "../MyProject/Resources/$(basename $i)"
fi
done
OTHER TIPS
Even shorter:
for i in `ls $1/resources`; do
if [ $i != databse.db -a $i != titles -a $i != map.pdf ]; then
svn export -q $1/resources/$i ../MyProject/Resources/$i
fi
done;
The -a
in the if expression is the equivalent of the boolean AND in shell-tests. For more see man test
Consider using a case statement:
for i in $(ls $1/resources); do
case $i in
database.db|tiles|map.pdf|map.png)
;;
*)
svn export -q $1/resources/$i ../MyProject/Resources/$i;;
esac
done
for i in `ls $1/resources`; do
if [ $i != "database.db" ] && [ $i != "tiles" ] && [ $i != "map.pdf" ] && [ $i != "map.png" ]; then
svn export -q $1/resources/$i ../MyProject/Resources/$i
For future reference, the new [[ test operator is preferred. The accepted answer is close and everything mentioned applies, but that answer will require lots of quoting and calls to multiple tests.
The preferred method would be something like:
for i in $1/resources/*; do
if [[ $i != "database.db" && $i != "tiles" &&
$i != "map.pdf" && $i != "map.png" ]]; then
svn export -q "$i" "../MyProject/Resources/$(basename $i)"
fi
done