我花了两个小时的大部分时间试图看看是否能找到一种方法将 bash 脚本的输出重定向到调用 bash 脚本的行。
我可以用来描述我正在寻找的内容的最佳示例是按下 [TAB] 时执行的完成函数:
$ech[tab] #--> $echo
我应该指出, 应该#-->
代表完成如何完成单词“echo”。
我能找到的最接近的是将某些选项设置为“echo”,以便\b\b
可以读取,并且标准输出可以更新同一行。但这不是我要找的。我希望能够直接输出到控制台输入中的当前行或下一行。这甚至可以通过 bash 脚本实现吗?
编辑:
感谢所有回复的人。我觉得我应该更新我原来的问题,甚至可能更改问题标题本身。
我的问题范围发生了以下变化:这不再是一个关于我可以或不能单独通过脚本完成什么的问题。我最初的目标是模拟完成“功能”,我逐渐了解到它实际上是一个内置 bash 命令。
看来我应该注意的特定库(以便甚至开始尝试模拟 bash 的制表符完成命令)是阅读线图书馆。 bash-completion 本身是用 C(++?) 实现的。
无论如何,再次感谢您富有洞察力的回复,如果有人有除上述文章所述之外的提示(可能来自个人使用 Readline 或 Completion 库),我期待阅读您的评论。
答案1
我可以通过两种方式解释这个问题 - 看来您要么想用不同的东西覆盖已经写入终端的内容 - 这很容易完成 - 或者您想以编程方式提供当前的交互式 shell 输入。
问题是——这些问题最终意味着两个截然不同的事情。很多人都会犯的一个错误(无论如何我确实做了一个 - 反复)就是将终端屏幕上打印的可视字符与键盘上键入的输入等同起来。但事实上,键盘比屏幕上的输出更容易处理——两者之间需要做很多工作才能将前者转变为后者。终端上的打印输出很方便——但它常常是谎言。
如果您想向 shell 提供输入,那么写入屏幕可能不会对您有帮助。当然,您可以这样做,发出一个用于向上移动终端线的标准 VT102+ 转义序列可能如下所示:
printf '\033[A'
...但是如果你这样做,看起来不会发生太多事情 - 这是因为 shell 没有读取它 - 它是写作到你所在的同一个地方。你可以做:
printf '\033[A'; cat
...实际查看它的作用,因为cat
这会阻止 shell 立即绘制新的提示符。你可以(大概)[
在括号和A
多行之间添加数字参数。您可以向下B
、向左D
、向右C
。将tput
调用的输出与termcap
您可以找到的序列一起保存到man termcap
命名变量中通常是人们采用的方式 - 确实如此。终端是很有趣的东西。
如果你想获得一些真正的乐趣,你可以尝试:
stty raw isig -echoctl; cat >/dev/null
xterm
在兼容的终端模拟器上(提供stty
支持-echoctl
- 但如果没有,你就不需要它)基本上应该允许您使用箭头键在终端屏幕上走动并在其中键入任何文本。但这些都不重要,因为您正在覆盖显示 - shell 根本不关心这一点。
如果你想影响一个 shell,你必须与它的标准输入对话。交互式 shell 通常不会过多听取您在这方面所说的内容,除非您在调用它时预先告诉它。否则它只会听键盘的声音 - 这就是它的用途(或者更准确地说,键盘是它的标准输入)。但你确实有选择。
编写交互式 shell 输入脚本的一个好方法是延迟它。例如,您可以获得一个虚拟提示 - 该提示基本上什么也不做,只是接受键盘输入并回显如下内容stderr
:
sh -niv 2>&1 >/dev/null | ...
它也不必是你的/bin/sh
——它会很好地工作bash
或无论什么。bash
将执行所有典型的readline
操作 - 甚至命令历史记录$PS1
- 但它会执行-n
某些操作并-v
详细地将所有输入打印到管道中。然后,您可以按照您喜欢的方式将其引导 - 可能bash
在稍微过滤后通过另一个管道到另一个管道。
你可以做很多这样的事情——但你无法回到过去。脚本启动后,最后一个命令就已经结束。您无法更改它 - 但您可以对其进行排列,以便过滤将来的命令。