加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl调用shell shell调用perl

发布时间:2020-12-16 00:39:11 所属栏目:大数据 来源:网络整理
导读:PERL中对SHELL命令的调用细节分析 本文将一步一步介绍为什么perl的system函数不能运行shell的builtin命令 ###################################################################### PERL 中对 SHELL 命令的调用细节 在 PERL 开发中,通常可以用 system 函数

PERL中对SHELL命令的调用细节分析

本文将一步一步介绍为什么perl的system函数不能运行shell的builtin命令
######################################################################
PERL中对SHELL命令的调用细节
PERL开发中,通常可以用system函数或 ``操作符来执行系统命令,但注意对
alias,bg,bind,break,builtin,cd,command,compgen,complete,continue,declare,dirs,disown,???????echo,enable,eval,exec,exit,export,fc,fg,getopts,hash,help,history,jobs,kill,let,local,logout,popd,printf,? pushd,? pwd,read,readonly,return,set,shift,shopt,source,suspend,test,times,trap,type,typeset,ulimit,umask,unalias,unset,waitshell内部命令(即在文件系统中无执行文件的命令)这样直接执行会出错,错误是无法找到该文件或目录。可以在命令前加sh –c来实现。而对cdumaskSESSION型命令,应该用PERL的内部函数chdirumask等来实现功能更可靠。
?
补:如果用system调用后台程序,肯定是希望不影响前台的CGI程序响应 HTTP请求,这时候注意,Firefox可以立刻得到 system调用后的输出,IE不行,会等到system调用的后台程序执行完才得到之后的HTTP输出。其实只需要在system调用的后台程序里加 >/dev/null 2>&1把输出重定向就可以解决IE的响应问题了。


######################################################################

举个例子:
# cat test.pl
system("cd");
print $?,"/n";
print $!,"/n";
# perl test.pl
-1
No such file or directory
#
######################################################################

2.?Shell如何执行命令 请点

2.1.?执行交互式命令 请点评

用户在命令行输入命令后,一般情况下Shell会forkexec该命令,但是Shell的内建命令例外,执行内建命令相当于调用Shell进程中的一个函数,并不创建新的进程。以前学过的cdaliasumaskexit等命令即是内建命令,凡是用which命令查不到程序文件所在位置的命令都是内建命令,内建命令没有单独的man手册,要在man手册中查看内建命令,应该

$ man bash-builtins

本节会介绍很多内建命令,如exportshiftifeval[forwhile等等。内建命令虽然不创建新的进程,但也会有Exit Status,通常也用0表示成功非零表示失败,虽然内建命令不创建新的进程,但执行结束后也会有一个状态码,也可以用特殊变量$?读出。

习题 请点评

1、在完成第?5?节 “练习:实现简单的Shell”时也许有的读者已经试过了,在自己实现的Shell中不能执行cd命令,因为cd是一个内建命令,没有程序文件,不能用exec执行。现在请完善该程序,实现cd命令的功能,用chdir(2)函数可以改变进程的当前工作目录。

2、思考一下,为什么cd命令要实现成内建命令?可不可以实现一个独立的cd程序,例如/bin/cd,就像/bin/ls一样?

2.2.?执行脚本 请点评

首先编写一个简单的脚本,保存为script.sh

例?31.1.?简单的Shell脚本

#! /bin/sh  cd .. ls

Shell脚本中用#表示注释,相当于C语言的//注释。但如果#位于第一行开头,并且是#!(称为Shebang)则例外,它表示该脚本使用后面指定的解释器/bin/sh解释执行。如果把这个脚本文件加上可执行权限然后执行:

$ chmod +x script.sh $ ./script.sh

Shell会fork一个子进程并调用exec执行./script.sh这个程序,exec系统调用应该把子进程的代码段替换成./script.sh程序的代码段,并从它的_start开始执行。然而script.sh是个文本文件,根本没有代码段和_start函数,怎么办呢?其实exec还有另外一种机制,如果要执行的是一个文本文件,并且第一行用Shebang指定了解释器,则用解释器程序的代码段替换当前进程,并且从解释器的_start开始执行,而这个文本文件被当作命令行参数传给解释器。因此,执行上述脚本相当于执行程序

$ /bin/sh ./script.sh

以这种方式执行不需要script.sh文件具有可执行权限。再举个例子,比如某个sed脚本的文件名是script,它的开头是

#! /bin/sed -f

执行./script相当于执行程序

$ /bin/sed -f ./script.sh

以上介绍了两种执行Shell脚本的方法:

$ ./script.sh $ sh ./script.sh

这两种方法本质上是一样的,执行上述脚本的步骤为:

图?31.1.?Shell脚本的执行过程

Shell脚本的执行过程


  1. 交互Shell(bashfork/exec一个子Shell(sh)用于执行脚本,父进程bash等待子进程sh终止。

  2. sh读取脚本中的cd ..命令,调用相应的函数执行内建命令,改变当前工作目录为上一级目录。

  3. sh读取脚本中的ls命令,fork/exec这个程序,列出当前工作目录下的文件,sh等待ls终止。

  4. ls终止后,sh继续执行,读到脚本文件末尾,sh终止。

  5. sh终止后,bash继续执行,打印提示符等待用户输入。

如果将命令行下输入的命令用()括号括起来,那么也会fork出一个子Shell执行小括号中的命令,一行中可以输入由分号;隔开的多个命令,比如:

$ (cd ..;ls -l)

和上面两种方法执行Shell脚本的效果是相同的,cd ..命令改变的是子Shell的PWD,而不会影响到交互式Shell。然而命令

$ cd ..;ls -l

则有不同的效果,cd ..命令是直接在交互式Shell下执行的,改变交互式Shell的PWD,然而这种方式相当于这样执行Shell脚本:

$ source ./script.sh

或者

$ . ./script.sh

source或者.命令是Shell的内建命令,这种方式也不会创建子Shell,而是直接在交互式Shell下逐行执行脚本中的命令。

######################################################################
再看Unix下面exec这个函数: 摘自APUE

8.10. exec Functions

8.10. exec Functions
We mentioned in Section 8.3 that one use of the fork function is to create a new process (the child) that then causes another program to be executed by calling one of the exec functions. When a process calls one of the exec functions,that process is completely replaced by the new program,and the new program starts executing at its main function. The process ID does not change across an exec,because a new process is not created; exec merely replaces the current processits text,data,heap,and stack segmentswith a brand new program from disk.

There are six different exec functions,but we'll often simply refer to "the exec function," which means that we could use any of the six functions. These six functions round out the UNIX System process control primitives. With fork,we can create new processes; and with the exec functions,we can initiate new programs. The exit function and the wait functions handle termination and waiting for termination. These are the only process control primitives we need. We'll use these primitives in later sections to build additional functions,such as popen and system.


#include <unistd.h>

int execl(const char *pathname,const char *arg0,

... /* (char *)0 */ );

int execv(const char *pathname,char *const argv []);


int execle(const char *pathname,...

/* (char *)0,? char *const envp[] */ );

int execve(const char *pathname,char *const

argv[],char *const envp []);

int execlp(const char *filename,

... /* (char *)0 */ );

int execvp(const char *filename,char *const argv []);


All six return: 1 on error,no return on success




The first difference in these functions is that the first four take a pathname argument,whereas the last two take a filename argument. When a filename argument is specified


If filename contains a slash,it is taken as a pathname.


Otherwise,the executable file is searched for in the directories specified by the PATH environment variable.
例如:
#/usr/bin/perl
system("sh ./first");
exit;
perl调用first.sh程序

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读