31

Bash code to print all folders:

for f in ~/*;
do
if [ $f  == '/home/sk/.' -o $f  == '/home/sk/..' ]; then
       true
  else
     echo "$f"
  fi
done

It works on bash. When i ran the code on z shell, it threw error:

 = not found

Then I converted [ into [[, ] into ]] to avoid this error in z shell and ran it on z shell. It threw next error:

condition expected: $f

With [[ and ]], bash also throws error as:

syntax error in conditional expression
syntax error near `-o'

Is there a POSIX standard to do string comparison in shell, that works across shells?

  • The POSIX standard for string comparison is case which supports an arbitrary number of shell patterns applied against a string and arbitrary associated shell commands you might apply when a match is true. – mikeserv Jun 08 '15 at 08:15

3 Answers3

37

There are various issues here. First, == is not standard. The POSIX way is =. Same goes for the -o. This one will work on both bash and zsh:

for f in ~/*;
do
if [ "$f"  = '/home/sk/.' ] || [ "$f"  = '/home/sk/..' ]; then
       true
  else
     echo "$f"
  fi
done

Note that your if is unneeded, dotfiles are ignored by default in both bash and zsh. You can simply write:

for f in ~/*; do echo "$f"; done

Or even

printf "%s\n" ~/*
terdon
  • 242,166
  • hi terdon, i have set shopt for dotglob set as off. But still i am getting . and .. inside the for loop in bash. so, i chose to do this fix... ls -a also lists the two entries - . and .. –  Jun 07 '15 at 14:54
  • @MadhavanKumar if you are seeing dotfiles, then dotglob is set somehow. They won't appear otherwise. – terdon Jun 07 '15 at 14:55
  • @MadhavanKumar In bash, set GLOBIGNORE=.:.. to skip . and .. – Gilles 'SO- stop being evil' Jun 07 '15 at 23:47
2

Try:

if [ "$f" = '/home/sk/.' ] || [ "$f" = '/home/sk/..' ]
Janis
  • 14,222
  • Are there any shells that will include dotfiles when expanding *? Neither bash nor zsh do. – terdon Jun 07 '15 at 14:36
  • @terdon; Not any shell that I know of. - Note that I was addressing just the OP's question in my answer, not any optimization beyond. – Janis Jun 07 '15 at 14:38
  • I understood that, hence my upvote. Since I'm pretty sure your knowledge of the shell ecosystem is far more extensive than my own, I thought I'd ask just in case :) – terdon Jun 07 '15 at 14:43
  • @terdon Neither does by default, but ksh, bash and zsh can be configured to include dot files. – Gilles 'SO- stop being evil' Jun 07 '15 at 23:46
0

Not a direct answer to your question, but the conditions are unnecessary, since in the POSIX spec * will not expand to . or ..

Also, you mentioned wanting to print all folders so then you would need to specify a trailing / in the pattern

So something like this should suffice to print all non-hidden directories..

for d in ~/*/
do
  [ -d "$f" ] && printf "%s\n" "${d%/}"
done

Note the the test for a directory entry, otherwise the pattern would get printed if there are no directories. ${d%/} is used to remove the trailing / induced by the pattern.

Scrutinizer
  • 1,142
  • 5
  • 7