shell Bash:通过编程方式获得命令的完成输出(例如,在变量中)

icomxhvb  于 2023-02-09  发布在  Shell
关注(0)|答案(3)|浏览(198)

如何以编程方式进入另一个命令的完成状态?
假设我的当前目录中有a1a2a3文件,那么我如何让我的命令调用ls a的自动完成功能来取回a1 a2 a3
这可能吗?

    • 说明和理由**:

我选择ls是因为人们可以与它联系起来。这是一个人为的例子,故意简单,以便人们可以不受干扰地理解这个问题,但不幸的是,这样的例子有时会让我们偏离主题。:)
让我试着举例说明这个特性的价值。我有一个名为build的命令,给定一个目录,它可以自动完成到可以在该目录中构建的目标。那些目标可能不对应于该目录中的文件,所以全局补全(* 和其他通配符)将不起作用。目标可能是由build命令从我不想解析的构建文件中挖掘出来的。换句话说:
build path/to/dir/标签
可能导致:

path/to/dir/a_target
path/to/dir/b_target

同样,a_target和b_target不是文件或目录。
build是一个预先存在的命令,我不能继续修改它以满足我的目的,而且它产生有效完成的方式也是我肯定不想知道或重新发明的。
现在假设我有一个完整的build able项目库,我的大部分工作,也就是我的大部分build工作只发生在一个项目中,换句话说,我总是把build作为my/project/directory下的目标。
到目前为止一切顺利。
我想写一个构建命令的 Package 器,这样我就不需要在每次运行它时都提供目录路径,我想让它知道我的首选项目目录(或者多个目录,为什么不呢),让我引用目标而不限定它们:
假设我有:

my/project/directory/a_target
my/project/directory/b_target

我想要这个:
mybuild标签
来给我:

a_target
b_target

基本上,我想修饰和简化build的行为,以满足我的特殊需要。
我需要为mybuild编写自己的完成代码,但我希望它依赖于build的完成,因为我不能让build的开发人员编写一个build listtargets命令来取悦我。(尽管那样会更健壮。)build命令已经有代码了,给定前缀就可以返回所有匹配的目标。build正在完成中,我需要利用它。
(Of当然,当我运行mybuild a_target时,我会确保它知道要运行build my/project/directory/a_target。我知道如何实现它,它不在这个问题的范围内。)
我希望这说明了为什么需要利用build命令的完成并将其作为黑盒调用。

cl25kdpy

cl25kdpy1#

这样做有点奇怪,您需要执行的命令取决于目录中文件的数量--没有、一个或多个,但下面的命令适用于示例情况:

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

正在自动完成的命令为

echo a

因此,将其作为字符流发送到交互式bashshell中,后跟两个制表符。bashstderr上生成自动完成输出,因此,将其重定向到stdout,并通过headtail传输,以便从整个输出中选择一行。

a1  a2  a3

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

echo a*

可能会更容易!

mctunoxg

mctunoxg2#

bash有一个类似的东西叫做globbing。
例如,在您的示例中,您可以运行以下命令

echo a*

这将产生:

a1 a2 a3

这在文件名中有空格的情况下非常有用

for i in a*
do
   echo $i
done

它对a1a 1都有效

i34xakig

i34xakig3#

自动完成是Shell提供的一项功能(例如bash)。shell会根据你要运行的命令的上下文和环境提供自动完成建议。例如,它知道一些命令可以在文件上运行,并且可以根据文件路径提供一些自动完成功能。但是命令本身并不知道它运行时使用的参数是如何指定的,或者由用户或者在自动完成的帮助下。

相关问题