好吧,我也想让它工作,我必须告诉大家set -o history ; set -o histexpand 方法将不在bash 4.x 中工作。无论如何,它并不打算在那里使用,因为有更好的方法来实现这一点。
首先,一个相当琐碎的例子,只是想在一个脚本中执行history:
(bash 仅限 4.x 或更高版本)
#!/bin/bash -i
history
简短的回答:它有效!
全新的-i 选项代表interactive,history 将 起作用。但目的是什么?
引用 OP 中 Michael H. 的评论:
“虽然您可以启用此功能,但这是一种不好的编程习惯。它会使您的脚本 (...) 难以理解。有一个因为默认情况下它是禁用的。你为什么要这样做?"
是的,为什么?这更深层的意义是什么?
嗯,有,我将在后续部分演示。
我的history 缓冲区已经变大了,而其中一些行是单行脚本,我真的不想每次都重新输入。但有时,我也想稍微改变这些行,因为我可能想给出第三个参数,而我之前总共只需要两个。
所以这是使用bash 4.0+ 功能调用history的理想方式:
$ history
(...)
<lots of lines>
(...)
1234 while IFS='whatever' read [[ $whatever -lt max ]]; do ... ; done < <(workfile.fil)
<25 more lines>
所以 1234 来自历史正是我们想要的行。当然,我们可以用 鼠标 移动到那里,将整条线夹在主缓冲区中吗?但是我们在 *NIX 上,那么为什么我们不能让我们的生活更轻松一些呢?
这就是我写下面这个小脚本的原因。同样,这仅适用于 bash 4.0+(但可能适用于 bash 3.x 和更早的版本以及上述 set -o ... 的东西......)
#!/bin/bash -i
[[ $1 == "" ]] || history | grep "^\s*$1" |
awk '{for (i=2; i<=NF; i++) printf $i" "}' | tr '\n' '\0'
例如,如果你把它保存为xselauto.sh,你可以调用
$ ./xselauto.sh 1234
history 第 1234 行的内容将在您的主缓冲区中,可以重复使用!
现在,如果有人仍然说“这没有 AFAICS 的目的”或“谁会需要这个功能?” - 好吧,我不在乎。但我不想再没有这个功能,因为我懒得每次都重新输入复杂的行。而且我也不想为历史中的每条标记线触摸鼠标,TBH。这就是 xsel 的用途。
顺便说一句,管道的tr 部分是一个肮脏的黑客,它将阻止命令被执行。对于“危险”的命令,在用户按下 Enter 键执行之前,始终让用户有一个查看的方式非常非常重要它。您可以省略它,但是...您已被警告。
附注这个 scriptlet 实际上是一个workaround,模拟在 bash shell 上键入的!1234。因为我永远无法让 ! 在脚本中直接工作(echo 永远不会让我透露历史行 1234 的 内容),所以我解决了这个问题只需 greping 我想复制的行。