È possibile stampare l'espansione della shell?


18

So che esiste un insieme specifico di regole che shell espande i comandi digitati dall'utente. (parliamo di bash shell.)

È possibile stampare un comando nel modulo dopo l'espansione della shell? Sembra essere una buona utility per imparare e assicurarsi che la shell espanda caratteri speciali.

per esempio

$ echo *

{all the filenames in current dir}

Voglio stampare il comando espanso, che è la seguente riga:

echo {all the filenames in .}

Risposte:


13

Basta usare echo... mettilo davanti al comando che vuoi espandere. Lo uso abbastanza frequentemente.

$ ls
one.txt
two.txt
three.dat
$ echo rm *.txt
rm one.txt two.txt
$ rm *.txt

È possibile utilizzare Homee Delper aggiungere / rimuovere rapidamente il precedente echo.

EDIT
Come sottolineato nei commenti, questo non funzionerà se il comando non è solo un semplice comando (come se si tratta di un forciclo, utilizza il tubo |, oppure &&o qualsiasi altra cosa del genere).


1
Questo è quello che faccio quando collaudo una sceneggiatura
Barmar,

Questo è ancora influenzato da altri token shell echo cat * | someprogramnon fa quello che potresti pensare da questa risposta.
Kroltan,

13

È possibile utilizzare set -x.

Ad esempio, considera lo script:

$ cat script.sh
set -x
echo *

Quando eseguito, mostra l' echoistruzione espansa prima di eseguirla effettivamente:

$ bash script.sh
+ echo file1 file2 file3 script.sh
file1 file2 file3 script.sh

E, come sottolinea Kundor, questo funziona anche in modo interattivo sulla riga di comando:

$ set -x
+ set -x
$ echo *
+ echo file1 file2 file3 script.sh
file1 file2 file3 script.sh

Documentazione

man bashspiega cosa set -xfa come segue:

Dopo aver espanso ogni comando semplice, per comando, comando caso, selezionare comando o aritmetica per comando, visualizza il valore espanso di PS4, seguito dal comando e dai suoi argomenti espansi o dall'elenco di parole associato.

Il valore predefinito per PS4è, come mostrato sopra, un segno più seguito da uno spazio.


2
E funziona bene anche in una shell interattiva (che penso che l'OP stia cercando).
Nick Matteo

7

Per una shell interattiva, premendo Ctrl+xseguito da *dopo aver digitato il pattern glob si modifica la riga di comando con quel pattern glob espanso. Dalla pagina man di bash:

glob-expand-word ( C-x *)

La parola prima del punto viene trattata come un modello per l'espansione del nome percorso e viene inserito l'elenco dei nomi file corrispondenti, sostituendo la parola. Se viene fornito un argomento numerico, viene aggiunto un asterisco prima dell'espansione del nome percorso.

Potresti anche essere interessato a espansioni glob-list ( Ctrl+x, g).


Sto usando bash da Mac OS. Ho provato ctrl + x, comando + x. Non sono sicuro che esegua modifiche alla riga di comando. potresti approfondire di più?
Weishi Zeng,

@WeishiZeng Non so perché non funzioni per te. Hai premuto Ctrl+x, *subito dopo aver digitato echo *e prima di premere il tasto Invio? Se il problema persiste, puoi modificare ~/.inputrce associare glob-expand-word a qualcos'altro.
jamesdlin,

contrl + x sposta il cursore sulla parola eco, ma non modifica nulla. "Ctrl + x, " cosa vuol dire ?? (è ctrl + x OR ctrl + ??) * è su Shift, quindi devo premere anche Shift per ottenere un *, giusto?
Weishi Zeng,

A destra, premi Ctrl+xseguito da Shift+8. Potresti provare a vedere se Ctrl+x, gfunziona o, come ho detto prima, assegnare la tua chiave nel .inputrcfile.
jamesdlin,

1

Se vuoi vedere come gli argomenti sono espansi o tokenizzati, puoi usare un programma o uno script che stampa i suoi argomenti. Ecco una implementazione in bash:

#!/bin/bash

for (( i = 0; i <= $#; ++i )); do
    printf 'argv[%d] = %s\n' $i "${!i}"
done

Supponendo di averlo inserito in un file chiamato printargs.sh(e reso eseguibile), si otterrebbe un output in questo modo

$ ./printargs.sh a{1..3}b
argv[0] = ./printargs.sh
argv[1] = a1b
argv[2] = a2b
argv[3] = a3b
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.