Significato di [“$ {1: 0: 1}” = '-']


18

Ho il seguente script per avviare un processo MySQL:

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

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

Cosa significa 1: 0: 1 in questo contesto?


1
Mi piacerebbe davvero conoscere la risposta, ma ritengo che questa sia una domanda troppo ristretta per SF. Sto votando per migrarlo sul sito Unix.
Massimo

Risposte:


19

È un test per -un'opzione di argomento tratteggiata, a quanto pare. È un po 'strano, davvero. Utilizza bashun'espansione non standard nel tentativo di estrarre il primo e solo il primo carattere $1. Il 0è l'indice carattere testa e 1è la lunghezza della stringa. In un modo [ testsimile potrebbe anche essere:

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

Nessuno dei due confronti è particolarmente adatto test, tuttavia, poiché interpreta anche -argomenti tratteggiati, motivo per cui utilizzo lo spazio iniziale lì.

Il modo migliore per fare questo tipo di cose - e il modo in cui viene fatto di solito - è:

case $1 in -*) mysqld_safe "$@"; esac

1
Vicino; il numero che segue i due due punti in ${1:0:1}è una lunghezza, non un indice.
Chepner,

In modo da bash con [[: [[ $1 == -* ]].
Arthur2e5,

2
Personalmente non credo -che questo sarà un problema per testquesto. POSIX fornisce definizioni dei significati in base al conteggio degli argomenti. Poiché non esiste tale opzione che accetta due argomenti, dovrebbe essere sicuro scriverlo in raw.
Arthur2e5,

@ Arthur2e5 - hai ragione - non dovrebbero essere un problema - e molto probabilmente non sono affatto problematici. è ancora uno strano modo di farlo - semplicemente non si adatta bene. ciò che [[ : [[fare?
Mikeserv,

1
@mikeserv Beh, dovresti guardare la pagina web (se stai leggendo questo altrove). Il mio commento è stato come 'con START_CODE [[END_CODE: START_CODE [[$ 1 == - *]] END_CODE'. Il primo [[è solo il nome della sintassi e i due punti sono solo una punteggiatura.
Arthur2e5,

11

Questo richiederà una sottostringa $1dal 0 ° al 1 ° carattere. Quindi otterrai il primo carattere e solo il primo carattere della stringa.

Dalla bashpagina man 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.

6

Sta testando che il primo carattere del primo argomento $1è un trattino -.

Il 1: 0: 1 sono i valori per il parametro di espansione: ${parameter:offset:length}.

Questo significa:

  • Nome: il parametro denominato 1, ovvero:$1
  • Inizio: dal primo carattere 0(numerato da 0).
  • Lunghezza: per 1 carattere.

In breve: il primo carattere del primo parametro posizionale $1.
L'espansione di quel parametro è disponibile in ksh, bash, zsh (almeno).


Se si desidera modificare la linea di test:

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

Opzioni Bash

Altre soluzioni bash più sicure possono essere:

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

Più sicuro perché questo non ha problemi con la quotazione (nessuna divisione viene eseguita all'interno [[)

POSIXly opzioni.

Per le shell meno recenti e meno capaci, potrebbe essere modificato in:

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

Solo il comando case è più resistente alle quotazioni errate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.