Evite executar o script se uma variável não estiver definida

7

Eu tenho um script parecido com:

c=0
for f in */*; do
cp -v "$f" "/myhome/CE$(printf '%0*d' 2 $BATCHNUM)-new-stuctures_extracted/test-$(printf '%0*d' 5 $c)"
c=$((c=c+1))
done

No entanto, o usuário deve fornecer uma chamada variável BATCHNUM e, caso contrário, eu preciso forçar esse script a parar de ser executado. Será melhor se eu puder forçar o script que chama esse script a parar também (ou até mesmo o script nº 1 que chama o script nº 2 que chama esse script).

    
por user40780 08.09.2015 / 18:22

5 respostas

13

A maneira mais rápida é provavelmente adicionar essas duas linhas ao início do script:

set -u # or set -o nounset
: "$BATCHNUM"

A primeira linha define a opção nounset no shell executando o script, que é anulado se você tentar expandir uma variável não definida; o segundo expande $BATCHNUM no contexto de um no-op, para acionar o aborto antes de fazer qualquer outra coisa.

Se você quiser uma mensagem de erro mais útil, poderá escrever:

if [[ -z "$BATCHNUM" ]]; then
    echo "Must provide BATCHNUM in environment" 1>&2
    exit 1
fi

Ou similar.

    
por 08.09.2015 / 18:27
11

Aqui você deseja verificar que BATCHNUM está definido e não é nulo.

O shell POSIX fornece uma Expansão do parâmetro para este trabalho. Apenas adicionando esta linha antes de usar BATCHNUM :

: "${BATCHNUM:?Variable not set or empty}"

ou melhor definir o valor padrão para BATCHNUM se o usuário não fornecer um:

: "${BATCHNUM:=3}"
    
por 08.09.2015 / 18:28
3
[ -n "$BATCHNUM" ] || { kill "$PPID"; exit 1; }
#Unless $BATCHNUM is defined and unempty, ask parent process to exit and exit w/ 1

Isso funcionará no bash e em um POSIX sh. Eu prefiro não diferenciar entre variáveis vazias e variáveis indefinidas (ou seja, eu não gosto de set -u , mas sou apenas eu).

    
por 08.09.2015 / 18:36
2

As linhas

if [ -z "$BATCHNUM" ]; then
    exit 2;
fi

verifique se há $BATCHNUM vazio. Com $PPID você pode fazer o mal que quiser ao seu pai ( kill $PPID ). Por assassinar seu avô, você precisa obter o ID do processo por outros meios, como observar os dados em /proc/$PPID .

No entanto, se seu pai morre, ele envia um sinal ( SIGHUP ) para você, então você precisa prendê-lo antes de começar a matar alguém:

trap '' SIGHUP

Atualização: Se você acha que precisa matar seus pais, está fazendo errado. Apenas retorne um código de saída significativo. O script pai deve verificar o código de retorno do script chamado e reagir de acordo.

    
por 08.09.2015 / 18:32
0

Para testar se BATCHNUM está definido e saia se não estiver:

if [ -n "${BATCHNUM-a}" ]; then
  echo >&2 "Fatal error: BATCHNUM not set"
  exit 2
fi

Se você também quiser rejeitar o caso em que BATCHNUM está vazio, use ${BATCHNUM:+a} em vez de ${BATCHNUM+a} . Para obter informações sobre a construção de expansão do parâmetro ${VARIABLE+TEXT_IF_NULL} , consulte, e. o manual do bash .

Não mate o processo pai. Você não sabe o que é o processo pai. Se algum script que chamar este precisar ser cancelado se esse script for anulado, verifique o status de saída desse script. Por exemplo. no roteiro 2:

script3 || exit $?

ou use set -e para abortar o script se houver comando retorna um status de falha (diferente de zero).

    
por 09.09.2015 / 02:50