Bash for 循环 - 循环中的命令可以添加到 shell 的历史记录中吗?

Bash for 循环 - 循环中的命令可以添加到 shell 的历史记录中吗?

在 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)设置 HISTCONTROLignorespaceor (这是andignoreboth的别名 )为 not保存以一个或多个空格开头的命令。如果您与其他用户在共享服务器上工作,并且您故意不希望将给定命令保存到历史记录中,以便其他人可以看到它,例如因为它包含您的密码或其他敏感信息,那么这尤其有用。ignorespaceignoredups

但即使命令之前没有空格:

$ var=5
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))

您很可能最终echo $((var--)) 在 ~/.bash_history 中只有一个条目,因为HISTCONTROL通常包含 ignoredups或前面提到的ignoreboth.所有这些都在 Bash 联机帮助页的部分中进行了描述,您可以在系统上HISTCONTROL调用。man bash

相关内容