Einfügen des Kommandozeilentextes vor der Ausgabe in stdout (für Pipe/Umleitung)

Einfügen des Kommandozeilentextes vor der Ausgabe in stdout (für Pipe/Umleitung)

Betrachten Sie die folgenden bashKonstrukte:

ls /usr/include/asm > list-redir.txt
ls /usr/include/asm | tee list-tee.txt

In diesem Fall sind list-redir.txtund list-tee.txtidentisch 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.txtwü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 >foound unterscheiden, ls /usr | tee fooaber es wird # ls /usran 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 ( erals 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 |ervor 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 1genau 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

verwandte Informationen