36
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

変数展開時の単語分割(word split)をマスターする

Last updated at Posted at 2013-02-01

シェルスクリプトは、スペース区切りの文字列が代入された変数を展開するとき、文字列をスペースの位置で分割して複数の文字列のように扱う。この挙動は Bash (をはじめとする Bourne shell 系のシェル)と Zsh とで異なってくる。

普通の変数について

Bash では、展開する変数をクォートしなければ単語分割が起きる。クォートすれば単語分割は起きず、スペースを含む1つの文字列として展開される。 Zsh では、変数をクォートするかしないかにかかわらず単語分割は起きない。ただし、 SH_WORD_SPLIT オプションをオンにすると Bash 準拠の挙動に変わる(デフォルトでオフ)。以下に単語分割の例を示す:

### 下準備

# 第1引数を echo する関数
function echo_first {
    echo $1
}

# スペース区切りの文字列を含む変数
var="a b c"



### Bash の場合

echo_first  $var  # => a
echo_first "$var" # => a b c

for v in $var; do
    echo $v
done
# => a
# => b
# => c

for v in "$var"; do
    echo $v
done
# => a b c



### Zsh (SH_WORD_SPLIT がオフ)の場合

echo_first  $var  # => a b c
echo_first "$var" # => a b c

for v in $var; do
    echo $v
done
# => a b c

for v in "$var"; do
    echo $v
done
# => a b c

Zsh で変数を強制的に単語分割するには ${=var} のように書く。記法の詳細ついては man zshexpn の "Parameter Expansion" を参照のこと。

特殊変数 $*$@ について

シェルスクリプトへのコマンドライン引数を格納する特殊変数 $*$@ は、それ自体がクォートされている場合の単語分割の挙動が異なる。 "$*" は、単語分割が起きずに1つの文字列として展開される。 "$@" は、引数に クォートされていないスペース が含まれる場合、そこで単語分割が起きる。

$* または $@ がクォートされていない場合、 Bash はスペースの位置で単語分割する。 Zsh はクォートされていないスペースの位置で単語分割する。

以下に例を示す:

wordsplit.sh
### クォートされたスペースを含む引数を与えて実行してみる

bash wordsplit.sh "a b" c
zsh  wordsplit.sh "a b" c



### Bash の場合

# $*: スペースで分割
for v in $*; do
    echo $v
done
# => a
# => b
# => c

# "$*": 分割なし
for v in "$*"; do
    echo $v
done
# => a b c

# $@: スペースで分割
for v in $@; do
    echo $v
done
# => a
# => b
# => c

# "$@": クォートされていないスペースで分割
for v in "$@"; do
    echo $v
done
# => a b
# => c



### Zsh (SH_WORD_SPLIT がオフ)の場合

# $*: クォートされていないスペースで分割
for v in $*; do
    echo $v
done
# => a b
# => c

# "$*": 分割なし
for v in "$*"; do
    echo $v
done
# => a b c

# $@: クォートされていないスペースで分割
for v in $@; do
    echo $v
done
# => a b c

# "$@": クォートされていないスペースで分割
for v in "$@"; do
    echo $v
done
# => a b
# => c
36
39
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?