Ist es möglich, die Shell-Erweiterung auszudrucken?

18

Ich weiß, dass es eine Reihe von Regeln gibt, die die vom Benutzer eingegebenen Befehle erweitern. (Lassen Sie uns über Bash Shell sprechen.)

Ist es möglich, nach der Shell-Erweiterung einen Befehl im Formular auszudrucken? Es scheint ein gutes Dienstprogramm zu sein, um zu lernen und sicherzustellen, wie die Shell Sonderzeichen erweitert.

z.B

$ echo *

{all the filenames in current dir}

Ich möchte den erweiterten Befehl ausdrucken. Dies ist die folgende Zeile:

echo {all the filenames in .}
Weishi Zeng
quelle

Antworten:

13

Verwenden echoSie einfach ... und stellen Sie es vor den Befehl, den Sie erweitern möchten. Ich benutze das ziemlich oft.

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

Sie können Homeund verwenden Del, um das Vorhergehende schnell hinzuzufügen / zu entfernen echo.

EDIT
Wie wies darauf hin , in den Kommentaren, das wird nicht funktionieren , wenn der Befehl nicht nur ein einfacher Befehl ist (wie wenn es sich um eine forSchleife, um das Rohr verwendet |, oder &&oder irgendetwas anderes ähnlich).

BenjiWiebe
quelle
1
Dies ist, was ich mache, wenn ich ein Skript
teste
Dies wird immer noch von anderen Shell-Tokens beeinflusst, echo cat * | someprogramdie nicht das tun, was Sie von dieser Antwort halten.
Kroltan,
13

Sie können verwenden set -x.

Betrachten Sie zum Beispiel das Skript:

$ cat script.sh
set -x
echo *

Beim Ausführen wird die erweiterte echoAnweisung angezeigt, bevor sie tatsächlich ausgeführt wird:

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

Und wie Kundor betont, funktioniert dies auch interaktiv auf der Kommandozeile:

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

Dokumentation

man basherklärt set -xwie folgt:

Zeigen Sie nach dem Erweitern jedes einfachen Befehls für Befehl, Groß- / Kleinschreibung, Auswahlbefehl oder Arithmetik für Befehl den erweiterten Wert von PS4 an, gefolgt von dem Befehl und seinen erweiterten Argumenten oder der zugehörigen Wortliste.

Der Standardwert für PS4ist, wie oben gezeigt, ein Pluszeichen, gefolgt von einem Leerzeichen.

John1024
quelle
2
Und es funktioniert auch gut in einer interaktiven Shell (nach der ich glaube, dass die OP sucht.)
Nick Matteo
7

Wenn Sie für eine interaktive Shell drücken und Ctrl+xanschließend *das Glob-Muster eingeben, wird Ihre Befehlszeile mit dem erweiterten Glob-Muster bearbeitet. Von der Bash-Manpage:

glob-expand-word ( C-x *)

Das Wort vor dem Punkt wird als Muster für die Pfadnamenerweiterung behandelt, und die Liste der übereinstimmenden Dateinamen wird eingefügt, wobei das Wort ersetzt wird. Wenn ein numerisches Argument angegeben wird, wird vor der Pfadnamenerweiterung ein Sternchen angehängt.

Möglicherweise interessieren Sie sich auch für glob-list-expansions ( Ctrl+x, g).

jamesdlin
quelle
Ich verwende Bash von Mac OS. Ich habe versucht, Strg + x, Befehl + x. Ich bin nicht sicher, ob es eine Befehlszeilenbearbeitung ausführt. könntest du mehr ausarbeiten?
Weishi Zeng
@ WeishiZeng Ich weiß nicht, warum es bei dir nicht funktioniert. Haben Sie Ctrl+x, *unmittelbar nach der Eingabe echo *und vor dem Drücken der Eingabetaste gedrückt? Wenn es immer noch nicht funktioniert, können Sie ~/.inputrcglob-expand-word ändern und an etwas anderes binden.
Jamesdlin
Strg + x bewegt den Cursor zum Wort Echo, bearbeitet aber nichts. "Strg + x ", was bedeutet das? (ist es Strg + x ODER Strg + ??) * ist auf Shift, also muss ich auch Shift drücken, um ein * zu bekommen, oder?
Weishi Zeng
Richtig, drücken Sie Ctrl+xgefolgt von Shift+8. Sie können versuchen, festzustellen, ob dies Ctrl+x, gfunktioniert, oder, wie bereits erwähnt, Ihren eigenen Schlüssel in der .inputrcDatei zuweisen .
Jamesdlin
1

Wenn Sie sehen möchten, wie Argumente erweitert oder mit einem Token versehen werden, können Sie ein Programm oder ein Skript verwenden, das die Argumente ausgibt. Hier ist eine Implementierung in bash:

#!/bin/bash

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

Angenommen, Sie haben das in eine Datei namens printargs.sh(und ausführbar gemacht) geschrieben, dann würden Sie eine Ausgabe wie diese erhalten

$ ./printargs.sh a{1..3}b
argv[0] = ./printargs.sh
argv[1] = a1b
argv[2] = a2b
argv[3] = a3b
jjlin
quelle