return value from eval

6

O manual do bash declara:

eval [arg ...]

          The  args  are read and concatenated together into a single com-
          mand.  This command is then read and executed by the shell,  and
          its  exit status is returned as the value of eval. If there are
          no args, or only null arguments, eval returns 0.

Eu tento

eval 'nonsense'
echo $?

O resultado é 0 .

Considerando que quando eu executo o comando entre aspas separadamente:

'nonsense'
echo $?

O resultado é 127 .

A partir do que está escrito no manual bash, eu esperaria que eval retornasse 127 quando pegasse o argumento nonsense as com aspas cruzadas.

Como obter o status de saída do argumento de eval ?

    
por Viesturs 04.01.2018 / 11:15

2 respostas

6

Quando você faz o seguinte -

'nonsense'
echo $?

Você basicamente está perguntando "Diga-me o status de saída quando tento obter a saída do comando sem sentido" a resposta para isso é "comando não encontrado" ou 127

Mas quando você faz o seguinte

eval 'nonsense'
echo $?

Você está perguntando "informe-me o status de saída do eval quando eu avaliar uma string vazia" (a saída do comando nonsense) que é igual a executar eval sem argumentos.

eval não tem problemas na execução sem argumentos e seu status de saída se torna 0

    
por 04.01.2018 / 11:40
11

Na verdade, é mais o seguinte:

$ 'nonsense'
bash: nonsense: command not found
$ echo "$?"
127

Isso é surpreendente aqui.

Pedimos que bash execute o comando que resulta do operador split + glob no stdout de nonsense . Como nonsense não produz saída, ele não executa nenhum comando, portanto você pode achar que o status de saída deve ser 0.

Mas, na verdade, quando uma linha de comando simples não possui argumento, apenas atribuição ou redirecionamento, o status de saída é o da última substituição de comando em atribuição e palavras normais (não em alvos de redirecionamento) executadas (embora a falha nos redirecionamentos seja também afeta o status de saída).

Isso é especialmente útil com atribuições.

Em:

output=$(grep pattern file)
status=$?

Você pode obter o status de saída e saída de grep , o que não seria possível se $? fosse o status de saída desse não-comando.

Em:

output=$(cmd1) cmd2

É aí que existem palavras de atribuição e palavras de argumento, o status de saída de cmd1 é ignorado. $? conterá o status de saída de cmd2 .

E também $output será definido apenas para cmd2 . Exceção para isso é quando cmd2 é um especial embutido.

eval é um especial .

$ a=0; a=1 eval; echo "$a"
1

Em bash e nas mais modernas caixas POSIX.

a='exit 5' eval; echo "$?"

ou

eval 'exit 5'; echo "$?"

A saída seria 0, pois é o resultado da execução de eval sem argumento. Mas esse não era o caso no shell Bourne ou no ksh88, onde para construtores especiais você obteria o status de saída de exit 5 .

Nestas conchas, você também encontrará:

$ a='exit 3' set x; echo "$?"
3

Como set é outro especial incorporado.

. é outro especial incorporado. No shell Bourne e no ksh88:

$ . /some/file 'exit 4'; echo "$?"
4

(contanto que /some/file não execute nenhum comando)

    
por 04.01.2018 / 13:32