sid*_*com 11 perl background system
#!/usr/bin/env perl
use warnings; use strict;
use 5.012;
use IPC::System::Simple qw(system);
system( 'xterm', '-geometry', '80x25-5-5', '-bg', 'green', '&' );
say "Hello";
say "World";
Run Code Online (Sandbox Code Playgroud)
我试过这个在后台运行xterm-command,但它不起作用:
没有找到shell的绝对路径:&
什么是使它运作的正确方法?
Gra*_*ean 19
Perl的系统功能有两种模式:
在第一种形式中,您必须小心转义可能对shell具有特殊含义的字符.第二种形式通常更安全,因为参数直接传递给正在执行的程序而不涉及shell.
在你的情况下,你似乎混合了两种形式.如果将&
字符传递给shell,则该字符仅具有"在后台启动此程序"的含义.在你的程序中,&符号作为xterm命令的第5个参数传递.
正如Jakob Kruse所说,简单的答案是使用单字符串形式system
.如果任何参数来自不受信任的来源,则必须使用引用或转义来使其安全.
如果你更喜欢使用多参数形式,那么你需要调用fork()然后使用exec()而不是system()
.
bri*_*foy 12
请注意,系统的列表形式特别是不处理诸如&
shell元字符之类的字符.
从perlfaq8的回答到如何在后台启动进程?
(由brian d foy提供)
没有一种方法可以在后台运行代码,因此在程序转移到其他任务之前,您无需等待它完成.流程管理取决于您的特定操作系统,许多技术都在perlipc中.
几个CPAN模块可能能够提供帮助,包括IPC :: Open2或IPC :: Open3,IPC :: Run,Parallel :: Jobs,Parallel :: ForkManager,POE,Proc :: Background和Win32 :: Process.您可能使用许多其他模块,因此请检查这些命名空间以获取其他选项.
如果您使用的是类Unix系统,那么您可以在系统调用中放弃,并在命令末尾添加&:
Run Code Online (Sandbox Code Playgroud)system("cmd &")
您也可以尝试使用fork,如perlfunc中所述(尽管这与许多模块将为您做的事情相同).
STDIN,STDOUT和STDERR是共享的
主进程和后台进程("子进程")共享相同的STDIN,STDOUT和STDERR文件句柄.如果两者都试图立即访问它们,可能会发生奇怪的事情.您可能想要为孩子关闭或重新打开这些.您可以通过打开管道来解决这个问题(请参阅在perlfunc中打开),但在某些系统上,这意味着子进程不能超过父进程.信号你必须捕获SIGCHLD信号,也可能是SIGPIPE.在后台进程完成时发送SIGCHLD.当您写入子进程已关闭的文件句柄时,会发送SIGPIPE(未处理的SIGPIPE会导致程序无声地死亡).这不是系统问题("cmd&").
植物大战僵尸
你必须准备在完成后"收获"子进程.
Run Code Online (Sandbox Code Playgroud)$SIG{CHLD} = sub { wait }; $SIG{CHLD} = 'IGNORE';
你也可以使用双叉.你马上等待()为你的第一个孩子,一旦它退出,init守护进程将等待你的孙子.
Run Code Online (Sandbox Code Playgroud)unless ($pid = fork) { unless (fork) { exec "what you really wanna do"; die "exec failed!"; } exit 0; } waitpid($pid, 0);
有关执行此操作的其他代码示例,请参阅perlipc中的信号.僵尸不是系统的问题("prog&").
你有没有尝试过?
system('xterm -geometry 80x25-5-5 -bg green &');
Run Code Online (Sandbox Code Playgroud)
http://www.rocketaware.com/perl/perlfaq8/How_do_I_start_a_process_in_the_.htm