我了解以下错误是由于!
用于历史扩展而导致的:
$ echo "Hello!Tim"
bash: !Tim: event not found
但是如果我将命令放入脚本并运行该脚本,则不会出现问题:
$ cat myscript
echo "Hello!Tim"
$ bash myscript
Hello!Tim
这是为什么? bash手册有提到原因吗?
答案1
是的,默认情况下仅对交互式 shell 启用历史扩展。
要为 shell 脚本启用它,请编写:
set -H
要在交互式 shell 中禁用它,请编写:
set +H
要确定当前是否启用历史扩展,请使用以下代码的某种形式:
case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac
在开始教授 shell 课程时,我仔细阅读了手册广泛地尝试建立“交互式外壳”的真正含义。这是一个漩涡问题,所以让我为您省去一些麻烦:
shell 有很多选项。当 shell 有控制终端时(或者使用-i
, 等等,等等,见下文)启动时,其中一些选项会以不同的方式初始化。
shell 的所有选项都可以单独更改。
当您试图精确定义“交互式 shell”时,它是一个具有欺骗性的术语。 它实际上只是选项设置的集合。
关于哪些设置使 shell 具有交互性或不具有交互性的问题是无法回答的;这变得很荒谬。这是恰恰同一个哲学问题忒修斯之船。
如果启动一个交互式 shell,但随后禁用历史扩展、使用 flag --noediting
、set --norc
、 close offexpand_aliases
等,那么 shell 在什么意义上是交互式的?或者,什么时候它不再具有交互性?这些问题你无法回答。
事实上,“交互式”只是各种 shell 选项集合的一个方便标签。同样是“非交互式”。一样;只是一系列行为的集合,每个行为都可以单独更改。
底线:shell 在“交互”启动时与“非交互”启动时的行为有所不同。尝试精确定义这些术语启动后很傻。只需查看 shell 的每个单独选项即可了解其行为。
我忘记了,除了我自己的研究之外,我还在这个网站上广泛发布了相关内容。