我想在 bash 中创建一个交互式 CLI。类似于 bash 为每一行添加前缀的方式user@host:~$
,我想在每一行添加前缀foobar>
。此功能可以在 Metasploit 或 mysqli 等 CLI 应用程序中看到,但它们使用单独的编程语言,而我想简单地使用 bash 脚本。此外,我需要向上/向下箭头键来使用该history
功能(或类似功能),允许用户轻松调出最后一个输入或之前的第 n 个输入。
在尝试创建解决方案时,我遇到了这个答案,它允许 bash 解释箭头键并使用history
. 这很好用,但是我很难将它与行前缀结合起来。我在这里找到了一个使用 coproc 预处理标准输出的解决方案并实现了一个版本,但是,这种方法既不适用于您正在输入的输入行,也不适用于使用带有history
. 我到目前为止的 bash 脚本如下:
exec 4>&1
coproc out (sed 's/^/foobar> /' >&4)
exec 1>&${out[1]}
printf "foobar> " >&4
while read -e x; do
history -s "$x"
echo $x
done
这是详细说明这两个问题的输出。正如您在下面看到的,我可以通过printf "foobar> " >&4
在 while 循环之前在上面的脚本中使用来为 cli 的第一行添加前缀。下面我boop
在第一行输入,echo 的输出被重定向到我的 coproc。但是在此之后,使用向上箭头将输入boop
带回将打印boop
没有我的前缀(如最后一行所示)。
$ ./test.sh
foobar> boop
foobar> boop
boop
我确实意识到,因为我在循环中没有 printf,所以我正在输入的行在第一次迭代后不会加前缀。稍后我可以通过重做循环来解决这个问题(尽管我担心将前缀行发送到前缀 coproc,因此需要双前缀)。我主要需要解决的是向上箭头输出没有加前缀。我假设这些信息是通过 发送的stdout
,但显然不是。我也尝试过stderr
以相同的方式重定向,但这会阻止终端在我输入时回显我输入的内容。
我需要一个解决方案来为 bash 脚本中的每一行添加前缀,无论它是基于我上面提供的脚本构建还是使用不同的方法。我还希望它尽可能优雅,因为我将使用这种技术构建一个 CLI 工具,并且希望尽可能少的额外开销。我认为重定向会为我做到这一点,但显然它比我最初想象的要复杂。
我并没有真正关注这
coproc
件事。在你的情况下read -p
似乎恰到好处。您可能希望使用单独的(非默认)历史文件。警告:脚本创建/用于
$HOME/.custom_history
保存其历史记录。测试解决方案后,手动删除文件。从这个问题借来的基本思想。