Significado de [“$ {1: 0: 1}” = '-']

15

Eu tenho o seguinte script para iniciar um processo do MySQL:

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

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

O que significa 1: 0: 1 neste contexto?

    
por user3521621 17.12.2015 / 00:12

3 respostas

16

É um teste para uma opção de argumento tracejado - , aparentemente. É um pouco estranho, na verdade. Ele usa uma expansão bash não padrão na tentativa de extrair o primeiro e somente o primeiro caractere de $1 . O 0 é o índice do caractere principal e o 1 é o tamanho da string. Em um [ test como esse também pode ser:

[ " -${1#?}" = " $1" ]
Nenhuma comparação é particularmente adequada para test , uma vez que interpreta - argumentos também - e é por isso que uso o espaço principal lá.

A melhor maneira de fazer esse tipo de coisa - e do jeito que normalmente é feito - é:

case $1 in -*) mysqld_safe "$@"; esac
    
por 17.12.2015 / 01:20
10

Isso levará uma substring de $1 do 0º para o 1º caractere. Então você vai pegar o primeiro caractere e apenas o primeiro caractere da string.

Na página do manual 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.
    
por 17.12.2015 / 01:12
6

Está testando que o primeiro caractere do primeiro argumento $1 é um traço - .

O 1: 0: 1 são os valores para a expansão do parâmetro: ${parameter:offset:length} .

Isso significa:

  • Nome: o parâmetro denominado 1 , por exemplo: $1
  • Início: do primeiro caractere 0 (numerado de 0).
  • Comprimento: para 1 caractere.

Em resumo: o primeiro caractere do primeiro parâmetro posicional $1 .
Essa expansão de parâmetro está disponível em ksh, bash, zsh (pelo menos).

Se você quiser alterar a linha de teste:

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

Opções de Bash

Outras soluções de bash mais seguras podem ser:

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

Mais seguro porque isso não tem problemas com citações (nenhuma divisão é executada dentro de [[ )

POSIXly options.

Para shells mais antigos e menos capazes, pode ser alterado para:

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

Apenas o comando case é mais resistente a cotações incorretas.

    
por 17.12.2015 / 11:18