8

编辑:这个问题最初是特定于 bash 的。我仍然宁愿有一个 bash 解决方案,但如果有一个很好的方法可以在另一个 shell 中执行此操作,那么了解它也会很有用!

好的,问题的顶级描述。我希望能够向 bash 添加一个钩子,这样,当用户输入时,例如$cat foo | sort -n | less,它会被拦截并翻译成wrapper 'cat foo | sort -n | less'. 我已经看到了在每个命令之前和之后运行命令的方法(使用 DEBUG 陷阱或 PROMPT_COMMAND 或类似的),但没有关于如何拦截每个命令并允许它由另一个进程处理。有没有办法做到这一点?

为了解释我为什么要这样做,以防人们有其他方法来解决它:

脚本之类的工具让您将您在终端中所做的一切记录到日志中(在某种程度上,就像 bash 历史记录一样)。但是,它们做得不是很好 - 脚本将输入和输出混合成一个大字符串,并与占据屏幕的 vi 等应用程序混淆,历史记录只为您提供输入的原始命令,而且它们都不起作用好吧,如果您同时将命令输入到多个终端。我想做的是捕获更丰富的信息——例如,命令、执行时间、完成时间、退出状态、stdin 和 stdout 的前几行。我还希望将其发送到某个可以愉快地多路复用多个终端的监听守护进程。

这样做的动机来自于试图理解探索性数据分析,如事后程序。有了这样更丰富的信息,就有可能生成关于所发生事件的体面报告,将一个命令的多次调用压缩成一个命令,其中前几个给出非零退出,通过搜索所有触及文件的内容来询问文件来自哪里,等等等等

4

2 回答 2

2

运行这个 bash 脚本:

#!/bin/bash
while read -e line
do
    wrapper "$line"
done

在其最简单的形式中,wrapper可以包括eval "$LINE". 你提到想要有时间,所以也许有time eval "$line". 您想捕获退出状态,因此后面应该跟一行save=$?. 而且,您想捕获标准输出的前几行,因此需要进行一些重定向。等等。

更多:Jo So 建议包含对多行 bash 命令的处理。以最简单的形式,如果 eval 返回“语法错误:文件意外结束”,那么您希望在继续之前提示输入另一行。更好的是,要检查正确的 bash 命令,bash -n <<<"$line"请在执行eval. 如果bash -n报告行尾错误,则提示输入更多输入以添加到 `$line'。等等。

于 2013-12-11T19:52:59.023 回答
0

Binfmt_misc 浮现在脑海中。Linux 内核具有允许识别任意可执行文件格式并将其传递给用户应用程序的能力。

您可以使用此功能来注册您的包装器,但它应该处理所有可执行文件,而不是处理任意可执行文件。

于 2013-12-11T23:51:38.403 回答