Bash

bash 回顯在命令行本身(不在腳本中)執行的命令行

  • August 3, 2018

出於文件目的,我的意思是從我執行的命令重定向到文件 stdout 和 stderr。例如,我會執行(我的命令沒有別名那麼簡單,ll但它可能無關緊要):

$ ll > out-err.dat 2>&1
$ cat out-err.dat
drwxr-xr-x 39 us00001 us00001    4096 jul 31 14:57 ./
drwxr-xr-x  3 root    root       4096 feb  2 06:06 ../
-rw-------  1 us00001 us00001   62226 jul 31 11:56 .bash_history
...

同樣出於文件目的,我想將我使用的命令行儲存在同一個輸出文件中。預期的行為和輸出是

$ [NEW COMMAND LINE]?
$ cat out-err.dat
[NEW COMMAND LINE]   <- This first line would contain the command line used
drwxr-xr-x 39 us00001 us00001    4096 jul 31 14:57 ./
drwxr-xr-x  3 root    root       4096 feb  2 06:06 ../
-rw-------  1 us00001 us00001   62226 jul 31 11:56 .bash_history
...

如何才能做到這一點? 我知道我可以編寫一個 bash 腳本並執行它,因此該命令將單獨記錄。我可以進一步編寫一個腳本來將命令行回顯到文件,然後通過重定向到同一個文件來執行它。我正在尋找一種可能的無腳本解決方案。


編輯:回饋一個不錯的答案。這不適合作為評論。

我用 command 測試過echo_command ll echo_command.sh ../dir > out-err.dat 2>&1

Script echo_command.sh,其中 I source,包含函式的定義。

../dir是一個不存在的目錄,強制一些輸出到stderr.

方法1:效果很好,除了兩個問題:

  • 它不理解別名(ll在這種情況下;用ls它替換時)。
  • 它不記錄重定向部分。

方法2:效果不好。現在重定向部分也列印出來了,但是命令行列印到螢幕而不是重定向到文件。


編輯:對發布的關於script實用程序的評論的回饋。它用途廣泛,使用scriptreplay.

script可以單獨呼叫,它會生成一個互動式 shell(它不會保留父 shell 的最近歷史記錄)

它也可以稱為script -c <command> <logfile>. 最後一種形式與 OP 的目標相對應,但它不會將命令本身儲存到日誌文件中。它產生(至少在基本情況下)與<command> > <logfile> 2>&1.

所以看起來這在這裡沒有用。

你可以使用這樣的函式:

echo_command() { printf '%s\n' "${*}"; "${@}"; }

例子:

$ echo_command echo foo bar baz
echo foo bar baz
foo bar baz
$ echo_command uname
uname
Linux

正如蒂姆肯尼迪所說,還有一個非常有用的script命令:

$ script session.log
Script started, file is session.log
$ echo foo
foo
$ echo bar
bar
$ echo baz
baz
$ exit
exit
Script done, file is session.log
$ cat session.log
Script started on 2018-07-31 16:30:31-0500
$ echo foo
foo
$ echo bar
bar
$ echo baz
baz
$ exit
exit

Script done on 2018-07-31 16:30:43-0500

更新

如果您還需要記錄重定向和基本上每個 shell 語法(請注意,我添加了一條小Command line:消息以輕鬆辨識正在執行的命令):

echo_command() {
 local arg
 for arg; do
   printf 'Command line: %s\n' "${arg}"
   eval "${arg}"
 done
}

請注意,您應該非常小心使用的引用eval

$ echo_command 'echo foo > "file 2"; cat "file 2"'
Command line: echo foo > "file 2"; cat "file 2"
foo

它還一次接受許多命令,而不僅僅是一個:

$ echo_command 'echo foo' 'echo bar' 'echo baz'
Command line: echo foo
foo
Command line: echo bar
bar
Command line: echo baz
baz

引用自:https://unix.stackexchange.com/questions/459697