Vala 的 Process.spawn_command_line_async 在解释 CLI 参数时遵循的规则是什么?

What are the rules that Vala's Process.spawn_command_line_async follows in interpreting CLI arguments?

具体来说,它如何解释引号中的参数或从标准输入(例如 <)重定向的特征?

我得到以下字符串:

string cmd = "mail -s 'Work Order #%s' -c %s -r email@server.com %s < email.txt".printf(wo.get_text(), ownmail, outmail.get_text());

当我使用

Posix.system(cmd);

命令按预期运行并发送了一封电子邮件,正文取自 email.txt。

当我使用

Process.spawn_command_line_async(cmd);

我从邮件命令中得到错误 'option -c is not found' 或类似的字样。当我丢失 Work Order #%s 周围的引号并转义空格时,电子邮件发送(主题行包含反斜杠)但不是从 email.txt 获取邮件正文,而是将 email.txt 作为电子邮件的另一个收件人(它显示在我的收件箱中,在“收件人:”部分下带有 'email.txt')。 < 被忽略或删除。为了检查一下,我使用了

Process.spawn_command_line_async("echo %s".printf(cmd));

这表明主题行周围的引号已被删除,但 < 仍然存在。我可以在我的程序中使用 Posix.system(),但为了简单和减少依赖性(并且更加地道),我更愿意使用 Process.spawn_command_line()。我错过了什么?

谢谢!

您可能想在 "".printf() 参数中使用 Shell.quote()Shell.unquote()

Vala Process.spawn_command_line_async() 函数绑定到 GLib 的 g_spawn_command_line_async () function. So a good place to start looking for more details is the GLib documentation. The GLib documentation states g_spawn_command_line_async() uses g-shell-parse-argv 来解析命令行。这会解析命令行,因此 "results are defined to be the same as those you would get from a UNIX98 /bin/sh, as long as the input contains none of the unsupported shell expansions."

该页面上还有 g_shell_quote () and g_shell_unquote (). These functions are bound to Vala as Shell.quote () and Shell.unquote ()

mail 只接受来自 STDIN 的消息正文,g_spawn_command_line_async() 不会处理重定向。因此,您将需要一个将正文作为参数的命令行工具,或者使用 Subprocess 之类的工具。

感谢 AIThomas 和 Jens 让我寻找正确的方向,我能够使用以下代码让它工作:

static int main(string[] args) {


    string subject = "-s " + Shell.quote("Work Order #123131");
    string cc = "-c ccemail@org.org";
    string frommail = "-r " + "senderemail@org.org";
    string[] argv = {"mail", subject, cc, frommail, "destinationemail@org.org"};
    int standard_input;
    int child_pid;



    Process.spawn_async_with_pipes (
        ".",
        argv,
        null,
        SpawnFlags.SEARCH_PATH,
        null,
        out child_pid,
        out standard_input,
        null,
        null);  

    FileStream instream = FileStream.fdopen(standard_input, "w");
    instream.write("This is what will be emailed\n".data);      

    return 0;   

}