MySQLプロセスを起動する次のスクリプトがあります。
if [ "${1:0:1}" = '-' ]; then
set -- mysqld_safe "$@"
fi
if [ "$1" = 'mysqld_safe' ]; then
DATADIR="/var/lib/mysql"
...
このコンテキストで1:0:1はどういう意味ですか?
どうやら-
の破線の引数オプションのテストです。ほんと少し奇妙です。 $1
から最初の最初の文字のみを抽出するために、非標準のbash
展開を使用します。 0
は先頭文字のインデックスで、1
は文字列の長さです。そのような[
test
では、次のようになることもあります。
[ " -${1#?}" = " $1" ]
どちらの比較もtest
には特に適していません。これは、-
の破線の引数も解釈するためです。そのため、ここで先行スペースを使用しています。
この種のことを行うための最良の方法-通常の方法-は次のとおりです。
case $1 in -*) mysqld_safe "$@"; esac
これは、0番目から1番目の文字までの$1
のサブストリングを取ります。したがって、文字列の最初の文字と最初の文字のみを取得します。
bash
3.2のmanページから:
${parameter:offset} ${parameter:offset:length} Substring Expansion. Expands to up to length characters of parameter starting at the character specified by offset. If length is omitted, expands to the substring of parameter start- ing at the character specified by offset. length and offset are arithmetic expressions (see ARITHMETIC EVALUATION below). length must evaluate to a number greater than or equal to zero. If offset evaluates to a number less than zero, the value is used as an offset from the end of the value of parameter. If parameter is @, the result is length positional parameters beginning at offset. If parameter is an array name indexed by @ or *, the result is the length members of the array beginning with ${parameter[offset]}. A negative offset is taken relative to one greater than the maximum index of the specified array. Note that a negative offset must be separated from the colon by at least one space to avoid being confused with the :- expan- sion. Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1.
最初の引数$1
の最初の文字がダッシュ-
であることをテストしています。
1:0:1はパラメーター拡張の値です:${parameter:offset:length}
。
つまり:
1
という名前のパラメーター、つまり$1
0
(0から始まる)。つまり、最初の位置パラメータ$1
の最初の文字です。
そのパラメータ拡張は、ksh、bash、zsh(少なくとも)で利用できます。
テスト行を変更したい場合:
[ "${1:0:1}" = "-" ]
他のより安全なbashソリューションは次のとおりです。
[[ $1 =~ ^- ]]
[[ $1 == -* ]]
これは引用の問題がないため安全です([[
内で分割は実行されません)
古い、能力の低いシェルの場合、次のように変更できます。
[ "$(echo $1 | cut -c 1)" = "-" ]
[ "${1%%"${1#?}"}" = "-" ]
case $1 in -*) set -- mysqld_safe "$@";; esac
Caseコマンドのみが、誤った引用に耐性があります。