🐚
Bashで展開される文字列と展開される時
Background
Bash使う時にどう言う文字列がどう言う時に展開されるかちゃんと把握せず、実際書いてみて期待と違ったら書き直す、みたいなことをずっとやってたので1回ちゃんと調べてまとめた。それぞれの展開機能自体の解説はしない[1]。
参照したドキュメント(bash v5.0のman)
Main Contents
主な[2]文脈として、 以下がある。
- unquoted
- "double quoted"
- 'single quoted'
- $'single quoted with dollar'[3]
主な[4]文字列展開として
- History Expansion(e.g.
!!
) - Parameter Expansion(e.g.
${VAR}
) - Command Substitution(e.g.
$(cmd)
, `cmd` ) - Arithmetic Expansion(e.g.
$((1+1))
) - Brace Expansion(e.g.
a{b,c}d
,{1..5}
) - Tilde Expansion(e.g.
~
) - Pathname Expansion(e.g.
dir/*
,/dev/video[0-3]
) - Backslash-Escaped Characters[5](e.g.
\n
)
これらのうちいつどれが展開されるかを表にすると以下。
unquoted | " " | ' ' | $' ' | |
---|---|---|---|---|
!! |
o | o | x | x |
${VAR} |
o | o | x | x |
$(cmd) |
o | o | x | x |
$((1+1)) |
o | o | x | x |
a{b,c}d |
o | x | x | x |
~ |
o | x | x | x |
dir/* |
o | x | x | x |
\n |
x | x | x | o |
Supplements
HERE DOCUMENTS
以下のようなテキストをHere Documentsと言う
<<HERE
text
HERE
これは $
系Expansion(${VAR}
, $(cmd)
, $((1+1))
)が展開される。 "double quoted" の History Expansionがないバージョン。
また、Here DocumentsにはHEREの部分にsingle quoteをつけることも出来る。
<<'HERE'
text
HERE
この場合、何も展開されない('single quoted'と同じ)。
Backslash-Escaped Characters
$' '
で展開されるbackslash-escaped charactersは以下(manから引用)
\a alert (bell)
\b backspace
\e
\E an escape character
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\' single quote
\" double quote
\? question mark
\nnn the eight-bit character whose value is the octal value nnn (one to three octal digits)
\xHH the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
\uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
\UHHHHHHHH
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)
\cx a control-x character
echo -e
と printf
でも backslash-escaped charactersの展開ができる。が、扱える文字列は微妙に違う。以下manから引用。
\a alert (bell)
\b backspace
\c suppress further output
\e
\E an escape character
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\0nnn the eight-bit character whose value is the octal value nnn (zero to three octal digits)
\xHH the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
\uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
\UHHHHHHHH
the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)
$" "
$' '
とは別に $" "
もある。これは普通の " "
に加えて、 gettext
と同じi18nの文字列置換機能が使用できる[6]。
$ locale -a
C
C.UTF-8
en_GB.utf8
en_US.utf8
ja_JP.utf8
POSIX
$ export TEXTDOMAIN=bash
$ export LANG=en_US.UTF-8
$ echo $"Done"
Done
$ gettext -s Done
Done
$ export LANG=ja_JP.UTF-8
$ echo $"Done"
終了
$ gettext -s Done
終了
参考: https://www.linuxjournal.com/content/internationalizing-those-bash-scripts
また $" "
はbackslash-escaped charactersが展開されない。
Discussion