Perl语言入门笔记 第十六章 进程管理

原创 2015年09月21日 02:08:26
=pod
第十六章  进程管理

身为程序员最棒的一面,就是能运行别人的程序,不必自己动手去写。

在perl里有一句话叫 “办法不止一种”

system函数:
		在perl中,启动子进程最简单的方法是用system函数,例如从perl调用Unix的date命令,需要告诉system要运行的外部程序的名字:
		system 'date';
		date运行时,创建了一个子进程
		
		system 'ls -l $HOME';
		
		利用shell来启动后台进程,
		system "long_running_command with parameters &";
			&使该条命令后台运行,此处可以用于需要长时间运行的程序
			
		system 'for i in *; do echo == $i ==; cat $i; done';
		该条指令会将当前目录中每个文件的文件名及其内容显示出来。
		
避免使用Shell:
		system操作符也可以用一个以上的参数来调用,如此一来,不管你给的文本有多复杂,都不会用到shell?????,做法如下:
			my $tarfile = 'something*wicked.tar';
			my @dirs = qw(fred|flintstone <barney&rubble> betty);
			system 'tar', 'cvf', $tarfile, @dirs;
			
			system操作符的返回值是根据子进程的结束状态来决定的,在unix里,退出0代表正常,非零退出值则代表有问题:
				unless (system 'date')
				{
					#返回0的话就代表执行成功
					print "We gave you a date, ok!\n";
				}

环境变量:
		现在需要运行系统的make程序,进而运行其他程序,并且想以你的私有目录作为寻找命令的首选位置,假如还要禁用IFS环境变量,以免make或者其后的命令做出不正常的举动,like this:
			$ENV{'PATH'} = "/home/rootbeer/bin:$ENV{'PATH'}";
			delete $ENV{'IFS'};
			my $make_result = system 'make';
			修改从父进程继承的环境变量并不能影响shell或者其他父进程。
	
exec函数:
		exec函数导致perl进程自己去执行任务,
		例如:要运行/tmp目录下的bedrock命令并带上-o args以及程序本身所调用的参数:
			chdir '/tmp' or die "Cannot chdir /tmp:$!";
			exec 'bedrock', '-o', 'args1', @ARGV;
		perl程序的主要功能是为另一个程序的运行设定运行环境,你可以预先修改环境变量,修改当前的工作目录,修改默认的文件句柄等等。
			$ENV{PATH} = '/bin:/usr/bin';
			$ENV{DEBUG} = 1;
			$ENV{ROCK} = 'granite';
			
			chdir '/user/fred';
			open STDOUT, '>', '/tmp/granite.out';
			exec 'bedrock';
			
用反引号捕获输出结果:
		无论用system还是exc,所执行命令的输出都会送往perl的标准输出,有时候我们感兴趣的是将输出结果捕获成字符串,以便后续处理,只要用反引号代替单引号或双引号就可以了。
		my $now = `date`;
		
		foreach (@function)
		{
			$about{$_} = `perldoc -t -f $_`;
		}
		
	qx也可以使用于捕获输出变量,主要是为了防止输出特殊字符
	qx'echo $$';
	
	不捕获输出时能不用反引号就不用反引号,可以使用system和exec
		
	标准输出和错误输出可以通过perl的合并信息,来输出
	如:my $output_with_errors = `frobnitz -enable 2>&1`;
	
	我们日常执行的命令大豆不会使用标准输入,所以没有这方面的问题,但是,如果date命令询问你要使用的时区(正如我们之前假设的), 这样就会有问题,因为提示文字"which time zone"会被送至标准输出,成为被捕获内容的一部分,然后date会试着从标准输入读取数据,由于用户根本看不到提示文字,所以他不知道该输入数据!没多久,用户就会打电话给你,说你的程序卡住了
	
	因此,请勿使用会读取标准输入的命令,如果你不太确定它是否会从标准输入读取数据,请将标准输入重定向为从/dev/null读取数据,如下所示:
		my $result = `some_questionable_command arg arg argh </dev/null`;
	这样,子shell就会将输入重定向到/dev/null,接着再执行那个交互式命令,这样就算它要求输入,也只会读到文件结束符。
	
从列表上下文中使用反引号:
	如果命令会输出很多行,那么在标量上下文中使用反引号会得到一个很长的字符串,其中包含换行符,不过,如果是在列表上下文使用同样的反引号,则会返回输出字符串按行拆分的列表。
	
	比如,unix下的who指令:
		merlyn	tty/42	dec 7 19:41
		rootbeer console	dec 2 14:35
		rootbeer	tty/12	dec 6 23:00
	标量上下文:
		my $who_text = `who`;
		my @who_lines = split /\n/, $who_test; #自行拆开
	列表上下文:
		自动拆分成多行
			my @who_lines = `who`;
			
=号是正则表达式,=~是绑定操作符  
		   
用IPC::System::Simple执行外部进程:
	IPC::System::Simple不是perl自带的模块,需要从CPAN下载
	
	可以代替system函数,但是执行更加健壮
	use IPC::System::Simple qw(system);
	
	my $tarfile = 'something*wicked.tar';
	my @dirs = qw(fred|flintstone<barney&rubble>betty);
	system 'tar', 'cvf', $tarfile, @dirs;
	他提供了一个systemx函数,在执行外部命令时不会通过shell调用,所以不会碰到shell导致意外的情况。
	如果要捕获外部命令的输出,只需要办system或systemx改成capture或者是capturex就可以了,他们的作用就好像使用反引号一样。
	my @output = capturex 'tar', 'cvf', $tarfile, @dirs;
	
	好模块。。。。。。。。。
	但是shell里面的命令调不到呀
	
通过文件句柄执行外部进程:
	要启发并发运行的子进程,请将命令放在open调用的文件名的部分,并且在它的前面或后面加上竖线,也就是管道符号,因此,有人将这种调用方式就做“管道打开”,在两个参数的行驶中,管道符号安放在要执行的命令的开头或者结尾:
		open DATE, 'date|' or die "Cannot pipe from date:$!"; 
		open MAIL, '|mail merlyn' or die "Cannot pipe to mail:$!";
		 '|'在指令的左边或右边代表输出还是输入
		 
	读取文件句柄:-|
	写入文件句柄:|-
	句柄需要关闭
	
	如果子进程不时有数据要送给父进程的话,就必须用管道了
	反引号和|-的输出结果的先后顺序
	
用fork进行深入和复杂的工作:
	system 'date';
	用fork可写成:
	defined(my $pid = fork) or die "Cannot fork:$!";
	unless($pid)
	{
		#能运行到这里的是子进程
		exec 'date';
		die "Cannot exec date:$!";
	}
	waitpid($pid, 0); #能运行到这里的是父进程
	
发送及接收信号:
	kill 2, 4201 or die "Cannot signal 4201 with SIGINT:$!";
	or:	kill 'INT', 4201 or die "Cannot signal 4201 with SIGINT: $!";
	or:	kill INT => 4201 or die "Cannot signal 4201 with SIGINT: $!";
	判断信号是否还存在,只是判断,并不是杀死
	unless(kill 0,$pid)
	{
		warn "$pid has gone away!";
	}	


	清理垃圾的函数:
		my $temp_directory = "/tmp/myprog.$$";#在这个目录下创建文件
		mkdir $temp_directory, 0700 or die "Cannot create $temp_directory: $!";
		sub clean_up
		{
			unlink glob "$temp_directory/*";
			rmdir $temp_directory;
		}
		sub my_int_handler
		{
			&clean_up();
			die "interrupted, exiting...\n";
		}
		
		$SIG{'INT'} = 'my_int_handler';
		...
		...
		&clean_up(); #。。。。。真正清理的部分

	只是终止当前程序,返回原来程序,只要在信号处理子程序中设置一个标记,然后再每行处理结束时检查它既可:
		my $int_count = 0;
		sub my_int_handler{$int_count++};
		$SIG{'INT'} = 'my_int_handler';
		...;
		while(<SOMEFILE>)
		{
			...;#一般要花几秒时间来执行的操作
			if($int_count)
			{
				#看到进来的中断信号了
				print "[processing interrupted...]\n";
				last;
			}
		}

\N:表示除换行符之外的所有字符
	
			
=cut

java语言程序设计基础篇第六章编程练习题

1 import java.util.Scanner; public class Main{ public static void main(String[] args){ final int...
  • gyhguoge01234
  • gyhguoge01234
  • 2016年07月05日 22:26
  • 3900

Java语言程序设计基础篇原书第十版第六章编程练习题答案

第六章 方法的部分代码,会尽快补全
  • Tanganling
  • Tanganling
  • 2016年11月27日 20:25
  • 3613

Perl笔记:Perl语言入门(第六版) - IO文件目录

输入与输出 读取标准输入 chomp($line = ); chomp截掉最后的换行符,标准输入。 while (defined($line = )) { print "$line"; } 简写whi...
  • u012740949
  • u012740949
  • 2014年01月27日 14:53
  • 1423

Perl语言入门笔记 第八章 用正则表达式进行匹配

#用正则表达式进行匹配 =pod m// = // = m%%,m||,m,m{},m(),匹配的时候根据需要写自己的定界符,像qw省略双引号定界符一样 模式匹配修饰符: 跟在定界符后面的,//...
  • q1241580040
  • q1241580040
  • 2015年09月21日 01:44
  • 2093

Perl语言入门笔记 第二章 标量数据

#!/usr/bin/perl -w =pod 数字: perl中的数字全部是以双精度浮点数存储的 数字很长时特俗写法,当然普通写法更支持: 61_298_040_283_768 0377 #...
  • q1241580040
  • q1241580040
  • 2015年08月23日 15:41
  • 304

Perl语言入门(第五版) 读书笔记(六)---文件测试

第十二章 文件测试 1. 文件测试操作符  -r:文件或目录对此(有效的)用户(effective user)或组是可读的  -w:文件或目录对此(有效的)用户或组是可写的  -x:文件或目录对此(有...
  • wangwenwen
  • wangwenwen
  • 2013年12月18日 18:36
  • 746

Perl语言入门笔记 第十章 其他控制结构(unless,until,elsif,for,last,next,redo,and,or)

=pod 第十章 其他控制结构 unless控制结构:和if相对 在条件为假时想要运行代码块,就用unless否则就用if: unless(judge){ } 伴随unless的else子...
  • q1241580040
  • q1241580040
  • 2015年09月21日 01:51
  • 619

<Perl语言入门>读书笔记 | 四. 子程序

读书笔记第四章:子程序。其实就是所谓的函数。
  • Titan0427
  • Titan0427
  • 2016年02月26日 01:52
  • 590

Perl语言入门笔记 第九章 用正则表达式处理文本

=pod #第九章:用正则表达式处理文本 用s///进行替换 s///查找替换功能 s/Barney/Fred/; #把Barney替换成Fred s/with (\w+)/against $1...
  • q1241580040
  • q1241580040
  • 2015年09月21日 01:47
  • 654

<Perl语言入门>读书笔记 | 三. 列表和数据

读书笔记的第三章,列表和数据,也就是所谓的数组。这里最重要的一个概念是,Perl中的表达式的上下文概念。...
  • Titan0427
  • Titan0427
  • 2016年02月25日 18:50
  • 586
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Perl语言入门笔记 第十六章 进程管理
举报原因:
原因补充:

(最多只允许输入30个字)