在 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