SSブログ

チルダ置換のbash, ksh93, zshの違い [sh]

シェルではコマンドや引数がチルダで始まるときに置換が行われる。

チルダの後に続く(スラッシュまでの)文字がユーザー名である場合、 そのユーザーのログインディレクトリに置換される。 たとえばrootのログインディレクトリが/rootのとき、次のようになる。

$ echo ~root
/root

この置換はクォートの内部では働かない。

$ echo "~root"
~root

ここまでの動作はbash, ksh93, zshで共通だ。

チルダに続くのが変数置換のとき、 bashではチルダ置換が行われないが、ksh93とzshでは行われる。

$ sudo bash -c 'echo ~$USER'
~root
$ sudo ksh -c 'echo ~$USER'
/root
$ sudo zsh -c 'echo ~$USER'
/root

チルダに続くのがクォートされた文字列のとき、 bashではチルダ置換が行われないが、ksh93とzshでは行われる。

$ bash -c 'echo ~"root"'
~root
$ ksh -c 'echo ~"root"'
/root
$ zsh -c 'echo ~"root"'
/root
$ bash -c 'echo ~"ro""ot"'
~root
$ ksh -c 'echo ~"ro""ot"'
/root
$ zsh -c 'echo ~"ro""ot"'
/root

チルダに続く文字列がエスケープされているとき、 bashではチルダ置換が行われないが、ksh93とzshでは行われる。

$ bash -c 'echo ~\r\o\o\t'
~root
$ ksh -c 'echo ~\r\o\o\t'
/root
$ zsh -c 'echo ~\r\o\o\t'
/root

チルダに続くのがコマンド置換のとき、3つのシェルのいずれでもチルダ置換が行われる。

$ bash -c "echo ~`echo root`"
/root
$ ksh -c "echo ~`echo root`"
/root
$ zsh -c "echo ~`echo root`"
/root
$ bash -c "echo ~$(echo root)"
/root
$ ksh -c "echo ~$(echo root)"
/root
$ zsh -c "echo ~$(echo root)"
/root

チルダ置換はコマンド、引数の先頭以外にも、変数代入の文脈で値をコロン区切りにした先頭部分でも行われる。

$ PATH=~root:~root
$ echo $PATH
/root:/root

しかし、どこが変数代入の文脈とみなされるかはbashとksh93, zshで異なるようだ。 ksh93とzshではコマンド前のA=Bやexportの文脈のみだが、bashではそれ以外でも変数代入の形をしていればチルダ置換をする。

$ bash -c 'echo PATH=~root:~root'
PATH=/root:/root
$ ksh -c 'echo PATH=~root:~root'
PATH=~root:~root
$ zsh -c 'echo PATH=~root:~root'
PATH=~root:~root

bashは上記のような無関係(?)な箇所でチルダ展開が起こることに注意しなければならない。 一方ksh93やzshでも PATH=... commandenv PATH=... command でチルダ展開の有無が異なることに注意しなければならない。 (前者の...の箇所では起こるが、後者の...の箇所では起こらない)

ここまでの例ではksh93とzshの動作は同じだったが、存在しないユーザーが指定された場合の動作はbash, ksh93とzshで異なる。 zshの場合はエラーとなり、ほかの2つではチルダがそのまま残される。

$ bash -c 'echo ~nosuchuser'
~nosuchuser
$ ksh -c 'echo ~nosuchuser'
~nosuchuser
$ zsh -c 'echo ~nosuchuser'
zsh:1: no such user or named directory: nosuchuser

もう一つ変なものを見つけてしまった。 チルダプレフィクス(チルダからスラッシュが来るまで、またはコマンドや引数が終わるまで)がチルダ単体の場合は自身の$HOMEで置換されるが、 bashとksh93ではコロンでもよい。zshはそうではない。

# bash -c 'echo ~:~'
/root:~
# ksh -c 'echo ~:~'
/root:~
# zsh -c 'echo ~:~'
~:~

nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。