Bash 在系统调用中以编程方式触发shell的自动完成事件并获取输出

Bash 在系统调用中以编程方式触发shell的自动完成事件并获取输出,bash,perl,shell,webmin,bash-completion,Bash,Perl,Shell,Webmin,Bash Completion,在提出实际问题之前,请先谈一谈我是如何理解这个想法的 我想在我的for Webmin中添加另一个很酷的功能 我已经制作了命令Shell模块的外观/感觉,如果它是。但是,由于它只是一个端口,因此几乎没有限制。当您点击Tab键(或基于系统的其他键:Esc+Esc和/或Ctrl+I)时,其中一个缺少shell自动完成功能 我的观点是让它在本地工作。我要用一个 XMLHttpRequest 调用服务器并将输入命令的一部分传递给实际的shell。当按下选项卡键时,将触发呼叫 例如,当您在Authentic

在提出实际问题之前,请先谈一谈我是如何理解这个想法的

我想在我的for Webmin中添加另一个很酷的功能

我已经制作了命令Shell模块的外观/感觉,如果它是。但是,由于它只是一个端口,因此几乎没有限制。当您点击
Tab
键(或基于系统的其他键:
Esc+Esc
和/或
Ctrl+I
)时,其中一个缺少shell自动完成功能

我的观点是让它在本地工作。我要用一个
XMLHttpRequest
调用服务器并将输入命令的一部分传递给实际的shell。当按下
选项卡
键时,将触发呼叫

例如,当您在Authentic Theme下拉列表中(您可以在上面的视频屏幕上看到它),并且当您键入(比方说,
xa
并点击
Tab
)时,事件将被触发并发出请求。然后服务器收到一个字符串
xa
,我们就可以开始了

我的问题是: 一,。在Perl中执行此类命令的最佳方式是什么
2.如何正确地避开这样的命令,以确保它不会被利用
3.如何在
系统()调用中以编程方式触发
选项卡
键(运行自动完成)
4.如何grep输出

在响应方面,以
xa
为例,我希望得到
xargs
的结果



我知道传递的命令可能有歧义,例如,当使用
sys
时,以及当autocomplete无法在单个
选项卡上工作时。我认为最好将其从当前问题的范围中排除。

如果您知道要生成的完成类型,可以使用
compgen
bash内置代码生成完成

最有用的是,
-c
选项将完成命令名,
-o default
将通过readline完成文件名。请参阅,其中大部分还可以与
compgen
一起使用

请注意,
system()
将把命令传递给
/bin/sh-c
,这可能与系统上的
bash
不同。因此,您可以执行以下操作:

system("/bin/bash", "-c", "compgen -c xa")
# xargs
# xattr
# etc…


如果您希望在给定特定字符串的情况下执行与bash相同的操作(而不是自己猜测完成类型),则需要实际调用tab-press(或等效项),这可以通过
expect
脚本来完成。这也是正确调用您可能已定义的任何自定义完成函数的唯一方法。例如,请参见bash完成处理的方式

下面是我尝试使用
expect
脚本打印出bash建议用于任意命令输入的完成:


调用
/script.exp string
将打印bash为
string
生成的实际完成情况,每行一个。如果没有建议填写,则不会打印任何内容。

将其拆分为多个问题。以目前的形式,它将不会吸引正确的答案。干杯@伊尼安,谢谢你的建议,但这一切都是相互关联的。然而,我真正的障碍是第3个,对于如何以编程方式触发它,我有一个答案就足够了。我不太明白你到底需要做什么。要捕获
选项卡
,如果这是您的意思,您需要处理键盘事件,例如。至于处理字符串,例如和,它非常关注security@zdim如果您转到普通shell并尝试使用
Tab
键来使用自动完成功能,您将看到它是如何工作的。当您键入
xa
并点击tab时,您将得到
xargs
。我的要点是将
xa
传递给shell,触发tab并获取输出。这是因为目前的限制。啊。。。为它打印ANSI序列怎么样?如果满足“传递到外壳”。我确实知道、使用并喜欢自动补全,每天很多次:)我有时甚至给自己的程序命名,以便在输入它们的名字时尽早完成:)是的,在阅读了对我问题的评论后,我现在正在做的就是这样。谢谢你,格里沙我们肯定需要避开输入,例如
xa
,以防止注入。唯一真正的问题是,我不想指定任何参数,而是希望
compgen
猜测它是文件、命令还是其他任何东西(这就是点击Tab的作用)。有没有办法做到这一点?遗憾的是,除了让bash来做之外,没有别的办法。我用
expect
脚本更新了答案,bash completion使用该脚本触发真正的完成测试。
system("/bin/bash", "-c", "compgen -o default file")
# file.txt
# file.pdf
# etc…
#!/usr/bin/env expect

log_user 0
set prompt {/@}
set cmd [lindex $argv 0]

# start bash with no startup files for clean env
spawn env INPUTRC=/dev/null PS1=$prompt bash --norc
expect $prompt

# set some readline variables for consistent completion output
send "bind 'set show-all-if-ambiguous on'\r"
expect $prompt
send "bind 'set bell-style none'\r"
expect $prompt
send "bind 'set completion-query-items -1'\r"
expect $prompt
send "bind 'set page-completions off'\r"
expect $prompt
send "bind 'set completion-display-width 0'\r"
expect $prompt

# run the completion
send "$cmd\t $prompt"
expect {
   # multiple matches, printed on separate lines, followed by prompt
   -re "^$cmd\r\n(.*)\r\n$prompt$cmd" { puts $expect_out(1,string) }
   # single match, completed in-place
   -re "^($cmd\[^ \]*)  $prompt" { puts $expect_out(1,string) }
   # single match, completed in-place, nospace
   -re "^($cmd\[^ \]+) $prompt"  { puts $expect_out(1,string) }
   # no match
   -re "^$cmd $prompt" { exit }
}