Menachem Shapiro wrote:
> 
> I came across this site that lists some common Bash pitfalls, as well
> as the correct way of doing things:
> http://wooledge.org/mywiki/BashPitfalls

Top 4 reasons why zsh is better than bash:

2) cp $file $target
   Under bash, this will split the words on whitespace. In zsh, there
   will be no word splitting by default.

   file="file one.txt"; target="file two.txt"

   $ cp $file $target
   cp: target `two.txt' is not a directory

   % cp $file $target
   % ls -b $file $target
   file\ one.txt  file\ two.txt
   
3) [ $foo = "bar" ]
   Under bash, $foo will be susceptible to word splitting. Under zsh, it
   is not. The quotes are superfluous, in either shell.

   foo="two words"
   
   $ [ $foo = "bar" ]
   bash: [: too many arguments

   % [ $foo = "bar" ]
   % echo $?
   1

   Because $foo did not contain the value bar, the comparison failed.

7) grep foo bar | while read line; do ((count++)); done
   Under bash, the value of count will not have changed as the pipelines
   are under subshells. zsh does not do this.

   for i in 1 2 3; do echo foo; done > bar
   unset count

   $ grep foo bar | while read line; do ((count++)); done
   $ echo :$count:
   ::

   % grep foo bar | while read line; do ((count++)); done
   % echo :$count:
   :3:
   
19) for i in {1..10}; do ./something &; done
    Inside of bash, it is illegal to place a ; directly after a &, as
    they both terminate the command.

    zsh allows this.

    cat <<EOF >something; chmod +x something
    > #!/bin/sh
    > echo -n .; sleep 10
    > EOF

    $ for i in {1..10}; do ./something &; done
    bash: syntax error near unexpected token `;'

    % for i in {1..10}; do ./something &; done
    .[2] 24209
    .[3] 24211
    .[4] 24213
    [5] 24215
    .[6] 24216
    .[7] 24218
    .[8] 24220
    .[9] 24222
    [10] 24224
    ..[11] 24225
    .

Some people may decry that zsh does not split on whitespace, inside a
variable, so they can't do a="1 2 3 4 5"; for i in $a; do [something
five time]; done. This is a throwback to sh, when there were no arrays,
so the scalars were overloaded to be arrays, and bash continues this
dubious tradition.

% a=(1 2 3 4 5); for i in $a; do [something five times]; done

All I did was change the "" to (). This has the added benefit of
allowing white space in the array values itself:
% a=("1 one" "2  two" "3   three" "4    four" "5     five");
% echo $a[5]
5     five

Bash also has arrays:
$ a=("1 one" "2  two" "3   three" "4    four" "5     five");
$ echo ${a[4]}
5 five
$ echo $a
1 one
$ echo ${a[*]}
1 one 2 two 3 three 4 four 5 five

The two are equivalent between zsh and bash array expansion:
 zsh: $a
bash: "[EMAIL PROTECTED]"

$ for i in "[EMAIL PROTECTED]"; do echo :"$i":;done
For fun, try removing the quotes. Try replacing the @ with *. Make a
table!

        for             echo    expected result         actual result
1)      "[EMAIL PROTECTED]"     :"$i":
2)      "[EMAIL PROTECTED]"     :$i:
3)      [EMAIL PROTECTED]               :"$i":
4)      [EMAIL PROTECTED]               :$i:
5)      "${a[*]}"       :"$i":
6)      "${a[*]}"       :$i:
7)      ${a[*]}         :"$i":
8)      ${a[*]}         :$i:

-john
chsh -s "`command which zsh`"


-- 
[email protected]
http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-list

Reply via email to