Bedeutung von [“$ {1: 0: 1}” = '-']

18

Ich habe das folgende Skript, um einen MySQL-Prozess zu starten:

if [ "${1:0:1}" = '-' ]; then
    set -- mysqld_safe "$@"
fi

if [ "$1" = 'mysqld_safe' ]; then
    DATADIR="/var/lib/mysql"
...

Was bedeutet 1: 0: 1 in diesem Zusammenhang?

user3521621
quelle
1
Ich würde wirklich gerne die Antwort wissen, aber ich denke, dies ist eine etwas zu enge Frage für SF. Ich stimme für die Migration auf die Unix-Site.
Massimo

Antworten:

19

Es ist -anscheinend ein Test für eine Option mit gestrichelten Argumenten. Es ist wirklich ein bisschen seltsam. Es wird eine nicht standardmäßige bashErweiterung verwendet, um zu versuchen, das erste und einzige Zeichen daraus zu extrahieren $1. Das 0ist der Kopfzeichenindex und das 1ist die Zeichenkettenlänge. In [ testetwa könnte es auch sein:

[ " -${1#?}" = " $1" ]

Keiner der Vergleiche eignet sich dafür besonders test, da er auch -gestrichelte Argumente interpretiert - weshalb ich dort den führenden Raum benutze.

Der beste Weg, so etwas zu tun - und wie es normalerweise gemacht wird - ist:

case $1 in -*) mysqld_safe "$@"; esac
mikeserv
quelle
1
Schließen; Die Zahl nach dem zweiten Doppelpunkt ${1:0:1}ist eine Länge, kein Index.
Chepner
In einer bashism Weise mit [[: [[ $1 == -* ]].
Arthur2e5
2
Persönlich glaube ich nicht, dass -dies hier ein Problem sein wird test. POSIX gibt Definitionen der Bedeutungen durch die Anzahl der Argumente an. Da es keine solche Option gibt, die zwei Argumente akzeptiert, sollte es sicher sein, sie in RAW zu schreiben.
Arthur2e5
@ Arthur2e5 - du hast recht - sie sollten kein Problem sein - und sind sehr wahrscheinlich überhaupt nicht problematisch. Es ist immer noch ein seltsamer Weg, es zu tun - es passt einfach nicht gut. Was bedeutet [[ : [[tun?
mikeserv
1
@mikeserv Nun, Sie sollten sich die Webseite ansehen (wenn Sie dies von einer anderen Stelle lesen). Mein Kommentar war wie 'mit START_CODE [[END_CODE: START_CODE [[$ 1 == - *]] END_CODE'. Der erste [[ist nur der Syntaxname und der Doppelpunkt ist nur eine Interpunktion.
Arthur2e5
11

Dies wird eine Teilzeichenfolge $1vom 0. bis zum 1. Zeichen annehmen . Sie erhalten also das erste Zeichen und nur das erste Zeichen der Zeichenfolge.

Von der bash3.2 Manpage:

  ${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.
Küken
quelle
6

Es wird geprüft, ob das erste Zeichen des ersten Arguments $1ein Bindestrich ist -.

Die 1: 0: 1 sind die Werte für die Parameter Expansion: ${parameter:offset:length}.

Das bedeutet:

  • Name: der benannte Parameter 1, dh:$1
  • Start: ab dem ersten Zeichen 0(nummeriert von 0).
  • Länge: für 1 Zeichen.

Kurz: Das erste Zeichen des ersten Positionsparameters $1.
Diese Parametererweiterung ist in ksh, bash, zsh (mindestens) verfügbar.


Wenn Sie die Testzeile ändern möchten:

[ "${1:0:1}" = "-" ]

Bash-Optionen

Andere sicherere Bash-Lösungen können sein:

[[ $1 =~ ^- ]]
[[ $1 == -* ]]

Sicherer, da dies keine Probleme mit dem Zitieren hat (kein Split wird im Inneren ausgeführt [[)

POSIXly-Optionen.

Für ältere, weniger leistungsfähige Shells könnte geändert werden:

[ "$(echo $1 | cut -c 1)" = "-" ]
[ "${1%%"${1#?}"}"        = "-" ]
case $1 in  -*) set -- mysqld_safe "$@";; esac

Nur der case-Befehl ist widerstandsfähiger gegen falsche Anführungszeichen.


quelle