O uso prático do comando “shell” embutido?

0

Eu verifiquei o shell-script /usr/bin/ssh-copy-id (parte do pacote openssh-client pelo menos no Debian) e ele contém a seguinte declaração if:

if [ "-i" = "$1" ]; then
  shift
  # check if we have 2 parameters left, if so the first is the new ID file
  if [ -n "$2" ]; then
    if expr "$1" : ".*\.pub" > /dev/null ; then
      ID_FILE="$1"
    else
      ID_FILE="$1.pub"
    fi
    shift         # and this should leave $1 as the target name
  fi
else

Qual é o sentido dos comandos shift ? Quer dizer, eu sei que shift n shell embutido muda n de argumentos da esquerda para a direita, mas qual é a razão para usá-lo neste script? Por que não usar:

if [ "-i" = "$1" ]; then
  if [ -n "$3" ]; then
    if expr "$2" : ".*\.pub" > /dev/null ; then
      ID_FILE="$2"
    else
      ID_FILE="$2.pub"
    fi
  fi
    
por Martin 26.06.2015 / 00:01

1 resposta

7

O que você faz depois de analisar a opção -i ? Existem mais argumentos para analisar. Se -i foi o primeiro argumento, depois de processá-lo, você precisa examinar o terceiro argumento. Na versão antiga de ssh-copy-id que você está vendo, -i é a única opção e o argumento depois disso é o nome do host de destino. Se -i não for passado, o nome do host de destino será o primeiro argumento.

if [ "$1" = "-i" ]; then
  …
  target_host_name=$3
else
  target_host_name=$1
fi

Isso não é dimensionado quando há várias opções. Você precisa acompanhar a posição atual na lista de argumentos.

if [ "${$position}" = "-i" ]; then
  …
  position=$((position+2))
fi
target_host_name=${$position}

O problema é que o que eu escrevi aqui não é uma sintaxe de shell válida. Não há uma construção fácil para obter o enésimo argumento; você pode fazer isso com eval , mas é estranho, e as antiguidades não conseguiam lidar com números de argumentos de vários dígitos.

Então, cada vez que uma opção é processada, ela é removida da lista, chamando shift . Se a opção tiver um argumento, chame shift 2 ou chame shift uma segunda vez para remover o argumento da opção. Então, depois de processar cada opção, o próximo argumento a processar é sempre $1 . É mais simples assim.

if [ "$1" = "-i" ]; then
  …
  shift 2
fi
…
target_host_name=$1
    
por 26.06.2015 / 03:15