我制作了一个简单的 bash 脚本来运行历史记录中的一系列命令,但它不起作用。
read -p "control + c to cancel"
for i in $(seq $1 $2)
do
!${i}
done
我像 一样运行它runrange 5 10
,它给了我!5: command not found
。如果我运行!5
,它工作正常!我该如何解决这个问题?
答案1
Bash 执行历史扩展的方式如下读完一行后的第一件事输入,因此它发生在扩展变量之前。!$
扩展中的!${i}
被视为指代最后一个参数前一个命令作为特殊情况的语法。
如果你想读取(或执行)历史记录中保存的命令,你可以使用history -p
, 或者fc
。
除此之外,请注意,您无法从外部脚本访问交互式 shell 的历史记录,并且有更直接的方法可以在脚本内部重复命令。
答案2
该脚本正在非交互式(当然也是非登录)会话中执行bash
;在任何非交互式 shell 会话中,历史记录扩展默认是禁用的。
您需要在脚本顶部添加(shebang 之后):
set -o history
启用历史记录set -o histexpand
(或set -H
)启用!
样式历史替换
默认情况下,记住非交互式会话的历史记录将保存在内存中,并在会话终止后刷新,因此即使以上两个选项也无法解决您的实际问题,真正的问题是您到目前为止输入了什么命令以及您期望在任何非交互式会话中获得什么?
为了理解这个想法,请在循环history
之前添加for
。