次のbash
構造を考えてみましょう。
ls /usr/include/asm > list-redir.txt
ls /usr/include/asm | tee list-tee.txt
この場合list-redir.txt
とlist-tee.txt
は同じで、予想されるファイルのリストを含みます。
$ head -5 list-redir.txt
a.out.h
auxvec.h
bitsperlong.h
boot.h
bootparam.h [...]
私の質問は - どのようにこれらのコマンドを作成し、コマンドラインテキストを標準出力の最初のエントリとして挿入することで、ファイルがコマンドラインで始まるようにすることができますか?たとえば、list-redir.txt
この場合、ファイルは次のようになります。
$ head -5 list-redir.txt
# ls /usr/include/asm
a.out.h
auxvec.h
bitsperlong.h
boot.h [...]
...これは、挿入されたコマンドラインの前に#文字を追加できることを意味します。
ls /usr/include/asm > list-redir.txt
元のコマンドライン(...)を入力するという点で、最小限の変更だけで使用できるものはありますか?
答え1
シンプルで醜いトリックは、以下を追加することです~/.bashrc
。
echorun(){
echo "# $@";
"$@"
}
その後、コマンドを実行できます
echorun ls /usr > list-redir.txt
ls /usr >foo
これにより、とを区別することはできませんが、先頭に追加されls /usr | tee foo
ます。# ls /usr
foo
答え2
次のことができます。
{ cmd="ls /usr/include/asm"
echo "$cmd" ; $cmd
} >./list-redir.txt
少なくとも私はそれがあなたがしたいことだと思います。これにより、次のような結果が生成されます。
$ cat <./list-redir.txt
###OUTPUT###
ls /usr/include/asm
#output of above command#
...
答え3
script
入力した内容や出力など、端末セッションを記録するコマンドを表示することもできます。ただし、バックスペースキーなどを含むすべての入力内容を記録するため、時々混乱することがあります。
$ 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
答え4
er
実際、@terdonの答えがより複雑なコマンドパイプラインでは機能しない可能性があることに気付いたので、次のエイリアス(@tendonの略語と呼ばれるechorun
)を考えました。
#alias er=' cat <(echo "# cmd: $(history 1)") - | tee' # last tee is not needed, so:
alias er=' cat <(echo "# cmd: $(history 1)") -'
デフォルトでは、最後のパイプまたはリダイレクトの直前にコマンドラインに挿入する必要があるという考えがあります。この時点で現在のコマンドラインを参照するのは|er
本当に幸運です。history 1
したがって、残りの標準入力(その時点の内容)の前に最初にエコーすることができますcat
。これで、次のことができます。
$ 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
したがって、私たちはいくつかのパイプのための完全なコマンドラインを持っており、何もエスケープすることを心配する必要はありません。デフォルトでは、er
最後のパイプに追加するだけです。唯一のマイナーな問題は履歴番号付けです(あまり気にしません。そうでなければ、awk
別名に追加の値を追加した可能性があります)。