Vala中调用GLib.Process执行带管道的外部命令异常求助
解决GLib.Process.spawn_command_line_sync执行带管道命令的报错问题
你遇到的ping: unknown host |错误,核心原因是**spawn_command_line_sync不会自动启动shell来解析管道、重定向这类shell语法**——它会把整个命令字符串里的内容都当成ping命令的参数,所以|被识别成了要ping的主机名,自然就报错了。
下面给你两种可行的解决办法:
方法一:通过shell执行命令
最简单的方式是把你的命令包裹在sh -c里,让shell帮你解析管道逻辑。修改后的代码如下:
public static int main (string[] args) { string command_out; string command_err; int exit_status; try { // 用sh -c包裹原命令,让shell处理管道 bool success = Process.spawn_command_line_sync ( "sh -c 'ping -c 1 191.98.144.1 | cut -d '/' -s -f5'", out command_out, out command_err, out exit_status ); if (success && exit_status == 0) { // 去除输出里的换行符 string ping_result = command_out.strip (); print ("Ping结果:%s ms\n", ping_result); } else { print ("执行失败:%s\n", command_err); } } catch (Error e) { print ("错误:%s\n", e.message); } return 0; }
注意:这种方法如果命令里包含用户输入的内容,要小心shell注入风险,比如用户输入的内容里有; rm -rf /这类恶意代码,会被shell执行。
方法二:手动创建进程管道(更安全高效)
如果想避免shell注入的风险,可以手动创建两个进程,把ping的输出作为cut的输入,直接通过GLib的API处理管道:
public static int main (string[] args) { try { // 创建ping进程的标准输出管道 FileDescriptor ping_out_fd; Process ping_proc = Process.new ( "/bin/ping", {"ping", "-c", "1", "191.98.144.1"}, null, ProcessFlags.STDOUT_PIPE, out ping_out_fd ); // 创建cut进程,把ping的输出作为它的标准输入 FileDescriptor cut_in_fd = ping_out_fd; string[] cut_args = {"cut", "-d", "/", "-s", "-f5"}; string cut_out; string cut_err; int cut_exit; bool cut_success = Process.spawn_sync ( null, cut_args, null, ProcessFlags.STDIN_PIPE, null, out cut_out, out cut_err, out cut_exit, cut_in_fd ); // 等待ping进程结束 ping_proc.wait (); if (cut_success && cut_exit == 0) { string ping_result = cut_out.strip (); print ("Ping结果:%s ms\n", ping_result); } else { print ("处理失败:%s\n", cut_err); } // 关闭文件描述符 FileUtils.close (ping_out_fd); } catch (Error e) { print ("错误:%s\n", e.message); } return 0; }
这种方式不需要依赖shell,直接通过进程间管道传递数据,安全性更高,也避免了shell解析带来的额外开销。
内容的提问来源于stack exchange,提问作者Alain
相关产品推荐
相关产品推荐

