Mam następujący skrypt do uruchomienia procesu MySQL:
if [ "${1:0:1}" = '-' ]; then
set -- mysqld_safe "$@"
fi
if [ "$1" = 'mysqld_safe' ]; then
DATADIR="/var/lib/mysql"
...
Co w tym kontekście oznacza 1: 0: 1?
Mam następujący skrypt do uruchomienia procesu MySQL:
if [ "${1:0:1}" = '-' ]; then
set -- mysqld_safe "$@"
fi
if [ "$1" = 'mysqld_safe' ]; then
DATADIR="/var/lib/mysql"
...
Co w tym kontekście oznacza 1: 0: 1?
Odpowiedzi:
-
Najwyraźniej jest to test na argument przerywaną. To naprawdę trochę dziwne. Używa niestandardowego bash
rozszerzenia w celu wyodrębnienia pierwszego i tylko pierwszego znaku $1
. Jest 0
to indeks znaku głowy, a 1
długość łańcucha. W [
test
podobny sposób może to być również:
[ " -${1#?}" = " $1" ]
Żadne porównanie nie jest jednak szczególnie przydatne test
, ponieważ interpretuje -
przerywane argumenty - dlatego używam tam wiodącej przestrzeni.
Najlepszym sposobem na zrobienie tego rodzaju rzeczy - i sposób, w jaki jest to zwykle wykonywane - jest:
case $1 in -*) mysqld_safe "$@"; esac
${1:0:1}
to długość, a nie indeks.
[[
: [[ $1 == -* ]]
.
-
będą one stanowić problem test
. POSIX podaje definicje znaczeń według liczby argumentów. Ponieważ nie ma takiej opcji, która wymaga dwóch argumentów, powinno być bezpiecznie napisać ją w stanie surowym.
[[ : [[
zrobić?
[[
to tylko nazwa składniowa, a dwukropek to tylko interpunkcja.
To zajmie podłańcuch $1
od 0 do 1 znaku. Otrzymasz więc pierwszy znak i tylko pierwszy znak ciągu.
Na stronie podręcznika bash
3.2:
${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.
Testuje, że pierwszym znakiem pierwszego argumentu $1
jest myślnik -
.
1: 0: 1 są wartości parametrów ekspansji: ${parameter:offset:length}
.
To znaczy:
1
, tj .:$1
0
(ponumerowanego od 0).W skrócie: pierwszy znak pierwszego parametru pozycyjnego $1
.
To rozszerzenie parametru jest dostępne w ksh, bash, zsh (przynajmniej).
Jeśli chcesz zmienić linię testową:
[ "${1:0:1}" = "-" ]
Inne bezpieczniejsze rozwiązania bash mogą być:
[[ $1 =~ ^- ]]
[[ $1 == -* ]]
Bezpieczniej, ponieważ nie ma to problemów z cytowaniem (wewnątrz nie jest wykonywany podział [[
)
W przypadku starszych, mniej zdolnych pocisków można zmienić na:
[ "$(echo $1 | cut -c 1)" = "-" ]
[ "${1%%"${1#?}"}" = "-" ]
case $1 in -*) set -- mysqld_safe "$@";; esac
Tylko polecenie case jest bardziej odporne na błędne cytowanie.