
在 bash 終端機上,如果我執行以下 for 迴圈:
for i in {1..5}; do echo $i; done
這些echo
命令不會加入到目前 shell 的歷史記錄中。是因為for(indo
部分)中的指令是在子shell中執行的嗎?如果是這樣,有沒有辦法在目前 shell 中運行它們?還是因為它for
當時正在「運行」而不可能?
編輯:鑑於它將整個 for 循環作為一個複合命令,如果我刪除 for 循環並將各個命令寫在五行中,難道不應該將所有五個都添加到歷史記錄中嗎?
我做了以下事情:
#!/bin/bash
set -o history
var=5
echo $((var--))
echo $((var--))
echo $((var--))
echo $((var--))
echo $((var--))
並使用運行腳本source
。仍然在歷史中,它只顯示了一個迴聲聲明echo $((var--))
,而不是全部五個。另一方面,如果echo $((var--))
我放置五個echo 5
, echo 4
, ...命令而不是五個echo 1
,則所有五個命令都會添加到歷史記錄中。
為什麼?
答案1
$HISTFILE
除非您在執行之前匯出,否則您的腳本一開始就不會將歷史記錄儲存到 ~/.bash_history 中。正如其中所說,man bash
這是因為:
如果未設定 HISTFILE,或歷史文件不可寫,則不會儲存歷史記錄。
HISTFILE
不是環境變量,它是 shell 變量,因此在子進程的腳本中不可用。即使您運行了這些命令
$ var=5
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
(注意提示符後的空格)在互動式會話中而不是腳本中,它們實際上不會保存到 ~/.bash_history 中,因為流行的 Linux 發行版(例如 Ubuntu)設置
HISTCONTROL
為ignorespace
or (這是andignoreboth
的別名 )為not儲存以一個或多個空格開頭的指令。如果您與其他使用者在共享伺服器上工作,並且您故意不希望將給定命令保存到歷史記錄中,以便其他人可以看到它,例如因為它包含您的密碼或其他敏感信息,那麼這尤其有用。ignorespace
ignoredups
但即使指令之前沒有空格:
$ var=5
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
您很可能最終echo $((var--))
在 ~/.bash_history 中只有一個條目,因為HISTCONTROL
通常包含
ignoredups
或前面提到的ignoreboth
.所有這些都在 Bash 線上說明頁的部分中進行了描述,您可以在系統上HISTCONTROL
呼叫。man bash