Non può capire la sostituzione del comando in guscio di pesce
-
17-09-2020 - |
Domanda
in sh:
~$ `echo ls`
bin/ Desktop/
.
Ma in pesce:
fish: Illegal command name “(echo ls)”
~% (echo ls)
.
(nota che il messaggio di errore viene visualizzato sopra la riga di comando.)
~% echo (echo ls)
ls
~% eval (echo ls)
bin/ Desktop/
fish: Illegal command name “(echo ls)”
exec (echo ls)
^
~% exec (echo ls)
.
Sembra che la sostituzione del comando funzioni solo come parametri di un comando, non come un comando stesso?Perché?
Bene, l'aiuto Doc dice
.Se un parametro contiene un set di parentesi, il testo racchiuso dalla parentesi sarà interpretato come un elenco di comandi.
Ma ancora, perché?
Soluzione
come
Poiché le sostituzioni dei comandi appartengono alle espansioni dei parametri e non sono consentite come comandi.
Un esempio simile:
in sh:
tmpls=ls
$tmpls
.
Ma in pesce:
% set cmd ls; $cmd
fish: Variables may not be used as commands.
...
.
Perché
In breve, è buono per verificabilità
Questo Articolo spiega i dettagli: < / P >.
.Poiché è consentito utilizzare le variabili come comandi in gusci regolari, è impossibile controllare attendibilmente la sintassi di uno script. Ad esempio, questo snippet di bash / codice zsh può o non può essere legale, a seconda della fortuna. Ti senti fortunato?
.if true; then if [ $RANDOM -lt 1024 ]; then END=fi; else END=true; fi; $END
Entrambi Bash e Zsh cercano di determinare se il comando nel buffer corrente è terminato quando l'utente preme il tasto di ritorno, ma a causa di problemi come questo, a volte falliscono. Peggio ancora, questo pezzo di codice perfettamente legale è respinto da bash:
.FI=fi; foo() { if true; then true; $FI; }
Il pesce evita questo tipo di problema, poiché le variabili non sono consentite come comandi. Tutto ciò che puoi fare con le variabili poiché i comandi possono essere eseguiti in modo molto più pulito utilizzando il comando EVAL o utilizzando le funzioni.
Per lo stesso motivo, le sostituzioni dei comandi non sono consentite come comandi.
(Nota: l'esempio citato non è giusto, dal momento che "se" e 'fi' non sono semplici comandi ma le parole riservate. Vedi i commenti qui sotto.)
Altri suggerimenti
ha a che fare con l'ordine di espansioni.
Da help expand-command-substitution
in fish
:
.Quando si combinano più espansioni dei parametri, vengono eseguite espansioni Nel seguente ordine:
* Command substitutions
* Variable expansions
* Bracket expansion
* Pid expansion
* Wildcard expansion
.
.Le espansioni sono eseguite da destra a sinistra, espansioni di staffa nidificate sono eseguiti dall'interno e fuori.
Da man bash
:
.L'ordine delle espansioni è: espansione del tutore, espansione di tilde, parametro, variabile e di espansione aritmetica e sostituzione del comando (fatto In una moda a sinistra a destra), la divisione delle parole e l'espansione del PathName.