Betrachten Sie die folgenden bash
Konstrukte:
ls /usr/include/asm > list-redir.txt
ls /usr/include/asm | tee list-tee.txt
In diesem Fall sind list-redir.txt
und list-tee.txt
identisch und enthalten die erwartete Dateiliste, z. B.
$ head -5 list-redir.txt
a.out.h
auxvec.h
bitsperlong.h
boot.h
bootparam.h [...]
Meine Frage ist: Wie kann ich einen solchen Befehl schreiben und den Befehlszeilentext als erstes in die Standardausgabe einfügen, sodass die Datei letztendlich mit der Befehlszeile als erste beginnt? Die Datei list-redir.txt
würde in diesem Fall beispielsweise folgendermaßen aussehen:
$ head -5 list-redir.txt
# ls /usr/include/asm
a.out.h
auxvec.h
bitsperlong.h
boot.h [...]
... was auch bedeutet, dass der eingefügten Befehlszeile das Zeichen # vorangestellt werden kann.
Gibt es irgendetwas, das ich hierfür verwenden könnte – aber mit möglichst geringen Änderungen bei der Eingabe im Vergleich zu den ursprünglichen Befehlszeilen ( ls /usr/include/asm > list-redir.txt
...)?
Antwort1
Ein einfacher (und hässlicher) Hack wäre, Folgendes zu Ihrem hinzuzufügen ~/.bashrc
:
echorun(){
echo "# $@";
"$@"
}
Sie führen Ihren Befehl dann wie folgt aus:
echorun ls /usr > list-redir.txt
Dadurch können Sie nicht zwischen ls /usr >foo
und unterscheiden, ls /usr | tee foo
aber es wird # ls /usr
an den Anfang von angehängt foo
.
Antwort2
Sie könnten einfach Folgendes tun:
{ cmd="ls /usr/include/asm"
echo "$cmd" ; $cmd
} >./list-redir.txt
Zumindest glaube ich, dass Sie das möchten. Das würde zu Ergebnissen wie diesen führen:
$ cat <./list-redir.txt
###OUTPUT###
ls /usr/include/asm
#output of above command#
...
Antwort3
Sie können sich auch den Befehl ansehen script
, der Ihre Terminalsitzung aufzeichnet, einschließlich Ihrer Eingaben und der gesamten Ausgabe. Das kann allerdings manchmal etwas chaotisch werden, da alles aufgezeichnet wird, was Sie eingeben, einschließlich aller Rücktasten usw.
$ script
Script started, file is typescript
$ ls /usr/include/asm
a.out.h ioctl.h mtrr.h setup.h termios.h
auxvec.h ioctls.h param.h shmbuf.h types.h
bitsperlong.h ipcbuf.h poll.h sigcontext32.h ucontext.h
boot.h ist.h posix_types_32.h sigcontext.h unistd_32.h
bootparam.h kvm.h posix_types_64.h siginfo.h unistd_64.h
byteorder.h kvm_para.h posix_types.h signal.h unistd.h
debugreg.h ldt.h prctl.h socket.h vm86.h
e820.h mce.h processor-flags.h sockios.h vsyscall.h
errno.h mman.h ptrace-abi.h statfs.h
fcntl.h msgbuf.h ptrace.h stat.h
hw_breakpoint.h msr.h resource.h swab.h
hyperv.h msr-index.h sembuf.h termbits.h
$ exit
exit
Script done, file is typescript
$ cat typescript
Script started on Sat 29 Aug 2015 10:32:52 AM EDT
$ ls /usr/include/asm
a.out.h ioctl.h mtrr.h setup.h termios.h
auxvec.h ioctls.h param.h shmbuf.h types.h
bitsperlong.h ipcbuf.h poll.h sigcontext32.h ucontext.h
boot.h ist.h posix_types_32.h sigcontext.h unistd_32.h
bootparam.h kvm.h posix_types_64.h siginfo.h unistd_64.h
byteorder.h kvm_para.h posix_types.h signal.h unistd.h
debugreg.h ldt.h prctl.h socket.h vm86.h
e820.h mce.h processor-flags.h sockios.h vsyscall.h
errno.h mman.h ptrace-abi.h statfs.h
fcntl.h msgbuf.h ptrace.h stat.h
hw_breakpoint.h msr.h resource.h swab.h
hyperv.h msr-index.h sembuf.h termbits.h
$ exit
exit
Script done on Sat 29 Aug 2015 10:33:00 AM EDT
Antwort4
Tatsächlich habe ich gerade festgestellt, dass die Antwort von @terdon mit einer komplizierteren Befehlspipeline möglicherweise nicht funktioniert. Daher habe ich mir den folgenden Alias ausgedacht ( er
als Abkürzung für @tendon’s echorun
):
#alias er=' cat <(echo "# cmd: $(history 1)") - | tee' # last tee is not needed, so:
alias er=' cat <(echo "# cmd: $(history 1)") -'
Die Idee ist im Grunde, dass |er
vor der letzten Pipe oder Umleitung in einer Befehlszeile eingefügt werden sollte; dann ist es in der Tat ein glücklicher Zufall, dass an dieser Stelle history 1
genau auf die aktuelle Befehlszeile verwiesen wird! Daher kann es zuerst von wiederholt werden, vor dem Rest der (an dieser Stelle befindlichen) Standardeingabe cat
. Und so können wir jetzt Dinge tun wie:
$ ls /usr/include/asm | grep 'p*.h' | grep 'osix' |er | tee mylist.txt
# cmd: 125 ls /usr/include/asm | grep 'p*.h' | grep 'osix' |er | tee mylist.txt
posix_types_32.h
posix_types_64.h
posix_types.h
$ ls /usr/include/asm | grep 's*.h' | grep 'ig' |er >> mylist.txt
$ cat mylist.txt
# cmd: 125 ls /usr/include/asm | grep 'p*.h' | grep 'osix' |er | tee mylist.txt
posix_types_32.h
posix_types_64.h
posix_types.h
# cmd: 126 ls /usr/include/asm | grep 's*.h' | grep 'ig' |er >> mylist.txt
sigcontext32.h
sigcontext.h
siginfo.h
signal.h
Somit haben wir eine vollständige Befehlszeile mit mehreren Pipes – und müssen uns keine Gedanken über Escapezeichen machen – im Grunde fügen wir einfach etwas zur letzten Pipe hinzu. Die einzige kleine Nörgelei ist die Verlaufsnummer (sie stört mich nicht so sehr, sonst würde ich eine weitere im Alias er
hinzufügen ).awk