Pergunta

Em sh:

~$ `echo ls`
bin/  Desktop/

Mas em peixes:

fish: Illegal command name “(echo ls)”
~% (echo ls)

(Observe que a mensagem de erro aparece acima da linha de comando.)

~% echo (echo ls)
ls
~% eval (echo ls)
bin/  Desktop/

fish: Illegal command name “(echo ls)”
exec (echo ls)
     ^
~% exec (echo ls)

Parece que a substituição de comandos funciona apenas como parâmetros de um comando, não como um comando em si?Por que?

Bem, o médico de ajuda diz

Se um parâmetro contiver um conjunto de parênteses, o texto entre parênteses será interpretado como uma lista de comandos.

Mas ainda assim, por quê?

Foi útil?

Solução

Como

Isso porque as substituições de comandos pertencem a expansões de parâmetros e não são permitidas como comandos.

Um exemplo semelhante:

em sh:

tmpls=ls
$tmpls

Mas em peixes:

% set cmd ls; $cmd
fish: Variables may not be used as commands.
...

Por que

Resumindo, é bom para verificabilidade

Esse artigo explica detalhes:

Como é permitido usar variáveis ​​como comandos em shells regulares, é impossível verificar com segurança a sintaxe de um script.Por exemplo, este trecho de código bash/zsh pode ou não ser legal, dependendo da sua sorte.Você se sente com sorte?

    if true; then if [ $RANDOM -lt 1024 ]; then END=fi; else END=true; fi; $END

Tanto o bash quanto o zsh tentam determinar se o comando no buffer atual é concluído quando o usuário pressiona a tecla Enter, mas devido a problemas como esse, às vezes eles falham.Pior ainda, este código perfeitamente legal é rejeitado pelo bash:

  FI=fi; foo() { if true; then true; $FI; }

Fish evita esse tipo de problema, já que variáveis ​​não são permitidas como comandos.Qualquer coisa que você possa fazer com variáveis ​​como comandos pode ser feito de uma maneira muito mais limpa usando o comando eval ou usando funções.

Pela mesma razão, substituições de comandos não são permitidas como comandos.

(Observação:O exemplo citado não é justo, pois 'if' e 'fi' não são comandos simples, mas palavras reservadas.Veja os comentários abaixo.)

Outras dicas

Tem a ver com a ordem das expansões.

De help expand-command-substitution em fish:

Ao combinar várias expansões de parâmetros, as expansões são realizadas na seguinte ordem:

 * Command substitutions
 * Variable expansions
 * Bracket expansion
 * Pid expansion
 * Wildcard expansion

As expansões são realizadas da direita para a esquerda, as expansões do suporte aninhado são realizadas de dentro e por fora.

De man bash:

A ordem das expansões é:Expansão de cinta, expansão, parâmetro, expansão variável e aritmética e substituição de comando (feita de maneira esquerda para a direita), divisão de palavras e expansão do nome do caminho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top