Bash:以编程方式获取命令的完成输出(例如,在变量中)

时间:2014-07-01 15:32:47

标签: bash shell tab-completion

如何以编程方式完成另一个命令?

假设我的当前目录包含文件a1a2a3,那么如何让我的命令调用ls a的自动完成功能以获取{{1} }}?

这可能吗?


澄清和理由

我之所以选择a1 a2 a3,是因为人们可以与之相关。这是一个人为的例子,但让我试着举例说明这个功能的价值。我有一个名为ls的命令,在给定目录的情况下,它可以自动完成可以在该目录中构建的目标。这些目标可能与该目录中的文件不对应。目标可能是由我不想解析的构建文件中的build命令挖掘的。换句话说:

build TAB TAB

可能会给:

build path/to/dir/

path/to/dir/a_target path/to/dir/b_target 是一个预先存在的命令,而不是我可以继续修改以适应我的目的。它提取目标的方式是我当然不想知道的。

现在假设我有一个build能够完成项目的整个存储库,而且我的大多数工作因此我的大多数build工作只在一个项目中进行。换句话说,我总是build build下的某个目标。

到目前为止一切顺利。

所以我想编写一个围绕build命令的包装器,每次运行它时都不需要我将它提供给目录路径。我希望它知道我首选的项目目录(或目录,为什么不),让我参考目标而不限定它们:

所以假设我有:

my/project/directory

我想要这个:

my/project/directory/a_target my/project/directoryb_target TAB TAB

给我:

mybuild

当然我需要为a_target b_target 编写完成代码,但我希望它依赖于mybuild的完成,因为我不能只是去询问开发人员{{1}编写build命令只是为了让我开心。在[{1}}完成时,该功能已经存在,我需要点击它。

(当然,当我运行build时,它会知道运行build listtargets,并且我知道如何实现,并且不在此问题的范围内。)

我希望这说明为什么我需要完成build命令并将其用作黑盒子。

3 个答案:

答案 0 :(得分:5)

这有点奇怪,您需要执行的命令取决于目录中的文件数 - 无,一个或多个。但是这个命令适用于示例案例:

echo echo a$'\t'$'\t' | bash -i 2>&1 | head -3 | tail -1

自动完成的命令是

echo a

所以将其作为字符流,后跟两个制表符,发送到交互式bash shell中。 bash会在stderr上生成自动完成输出,因此将其重定向到stdout并通过headtail管道输出以从整体中选择一行输出。在这种情况下,这会产生单行输出

a1  a2  a3 

但是,正如其他人所说,只是使用

echo a*

可能更容易!

答案 1 :(得分:1)

Bash有类似的东西叫做globbing。

因此,例如在您的情况下,您可以运行命令

echo a*

哪会产生:

a1 a2 a3

如果您可以说文件名中有空格,这非常有用

for i in a*
do
   echo $i
done

它适用于a1以及a 1

答案 2 :(得分:0)

自动完成功能是shell提供的功能(例如bash)。 shell将尝试根据您尝试运行的命令的上下文和环境提供自动完成建议。例如。它知道某些命令可以在文件上运行,并且可以根据文件路径提供一些自动完成功能。但是命令本身并不知道如何通过用户或在自动完成的帮助下指定它运行的参数。