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;
}
具体来说,它如何解释引号中的参数或从标准输入(例如 <)重定向的特征?
我得到以下字符串:
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;
}