交互式 bash 脚本:为所有行添加字符串前缀

交互式 bash 脚本:为所有行添加字符串前缀

我想在 bash 中创建一个交互式 CLI。与 bash 为每行添加前缀的方式类似user@host:~$,我想为每行添加前缀foobar>。此功能可以在 Metasploit 或 mysqli 等 CLI 应用程序中看到,但它们使用单​​独的编程语言,而我只想使用 bash 脚本。此外,我需要向上/向下箭头键来使用该history功能(或类似的功能),允许用户轻松调出最后一个输入或之前的第 n 个输入。

在尝试创建解决方案时,我遇到了这个答案它允许 bash 解释箭头键并使用 调出最后的输入history。这很有效,但是我很难将其与行前缀结合起来。我找到了解决方案这里然而,要使用 coproc 预处理 stdout 并实现此方法的一个版本,此方法既不适用于您正在键入的输入行,也不适用于使用带有 的箭头键拉出的行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 工具,并且希望尽可能少的额外开销。我认为重定向可以为我做到这一点,但显然它比我最初想象的要复杂。

答案1

我并没有真正关注这coproc件事。在你的情况下read -p似乎是正确的。您可能想使用单独的(非默认)历史文件。

警告:脚本创建/使用$HOME/.custom_history来保存其历史记录。测试解决方案后,手动删除该文件。

#!/bin/bash

# History management
hfile="$HOME/.custom_history"
HISTCONTROL=ignoreboth
history -r "$hfile"
trap 'history -a "$hfile"' exit

# Main loop
while read -ep 'foobar> ' x; do
   history -s -- "$x"
   printf '%s\n' "$x"
done

基本思想借鉴自这个问题

相关内容