4

Bash バージョン 4.2.25 を実行しています。これが私のコードです:

#!/usr/bin/env bash

string="one:two:three:four"

# without quotes
IFS=: read -ra array_1 <<< $string
for i in "${array_1[@]}"; do printf "i = [$i]\n"; done
# output:
# i = [one two three four]

# with quotes
IFS=: read -ra array_2 <<< "$string"
for i in "${array_2[@]}"; do printf "i = [$i]\n"; done
# output:
# i = [one]
# i = [two]
# i = [three]
# i = [four]

動作の違いは何によって説明されますか?

4

2 に答える 2

3

bash 4.2.46 および bash 4.3.30 を使用する Linux で問題を再現できません。ただし、説明されている動作を示す適応バージョンを次に示します。

string="one:two:three:four"
IFS=:

read -ra array_1 <<< $string
for i in "${array_1[@]}"; do printf "i = [$i]\n"; done
# i = [one two three four]

read -ra array_2 <<< "$string"
for i in "${array_2[@]}"; do printf "i = [$i]\n"; done
# i = [one]
# i = [two]
# i = [three]
# i = [four]

これは、変数が実際にはスペースで分割されているのではなく、変数が分割されているために発生します$IFS(デフォルトではスペース、タブ、および改行)。

をオーバーライド$IFSしたため、コロンを含む値の引用には注意が必要です。スペースはもはや問題ではありません。

ソース コードは、Bash がwrite_here_stringを介して呼び出されるにスペースをハードコーディングすることを示しています。にスペースが含まれていない場合、複数の単語に展開される文字列は、同様の行に沿ってトークンにならず、違いがより顕著になります。string_listIFSread

PS: これは、変数の内容がわかっている場合でも、常に変数をクォートする必要がある理由の良い例です。

于 2017-01-10T20:35:30.727 に答える