ShellScript
Bash
Zsh

気を付けて!!Bashとzshの微妙な違い

More than 1 year has passed since last update.

Shell Script Advent Calendar 2015 5日目の記事です。

モノローグ

「Bash凄い!zshもっと凄い!!どうせ使うなら凄い方がいい」、という安直な考えで、普段zshを使ってます。当然スクリプトを書いたりしてるのですが、どうせ書くならBashでもzshでも使える方がいいですよね♩
基本的にBashで動けばzshでも同じように動くんですが、注意しなければならない2つのことを紹介します。

チルダ置換編

シェルではコマンドや引数がチルダ(~)で始まる場合、置換が行われます。
例えば、チルダの後の文字列がユーザー名である場合、そのユーザーのログインディレクトリに置換されます。

$ echo ~root
/root
$ echo "~root"
~root

チルダに続く文字列がコマンド置換の場合も、チルダ置換が行われます。

$ "echo ~`echo root`"
root/

ここまでは両シェル共通です。

変数置換

チルダに続く文字列が変数の場合、Bashではチルダ置換は行われませんが、zshでは置換されます。

//bashの場合
$ bash -c 'echo ~$USER'
~root
//zshの場合
$ zsh -c 'echo ~$USER'
/root

チルダに続く文字列がクォートされている場合も、Bashでは置換は行われませんが、zshでは置換されます。

//bashの場合
$ bash -c 'echo ~"root"'
~root
$ bash -c 'echo "r""oot"'
~root

//zshの場合
$ zsh -c 'echo ~"root"'
/root
$ zsh -c 'echo ~"r""oot"'
/root

チルダに続く文字列がエスケープされているときも同様に、Bashでは置換されずzshでは置換されます。

//Bashの場合
$ bash -c 'echo ~\r\o\o\t'
~root

//zshの場合
$ zsh -c 'echo ~\r\o\o\t'
/root

存在しないユーザー指定した場合

存在しないユーザーをチルダ置換すると、Bashではチルダがそのまま残るのですが、zshではエラーになります。

//Bashの場合
$ bash -c 'echo ~ghost'
~ghost

//zshの場合
$ zsh -c 'echo ~ghost'
zsh:1: no such user or named directory: ghost

配列編

Bashの配列は他のプログラミング言語と同様に0から始まるのですが、zshは何故だか分かりませんが1から始まります。よく使うであろう配列の仕様が違うのは困りますねぇ。
・Bashの場合

$ arr=(a b c)
$ for i in {0...3}; do
$ echo "$arr[$i] = ${arr[$i]}"
$ done;

arr[0] = a
arr[1] = b
arr[2] = c
arr[3] =

・zshの場合

$ arr=(a b c)
$ for i in {0...3}; do
$ echo "$arr[$i] = ${arr[$i]}"
$ done;

arr[0] =
arr[1] = a
arr[2] = b
arr[3] = c

解決法

zshで配列を0番からに出来るksharraysというオプションを使ってやれば、Bash同様に0番からになります。

ひとこと

シェルは奥が深すぎて、しばらく初心者の域を脱せそうにないです。゚(゚´Д`゚)゚。 

明日は@akinomyogaさんです!