execv的用法 linux
2012-09-08 11:16:41 jeffreyst 阅读数 2010
  1. 函数原型

int execv(const char *progname, char *const argv[]);   //#include <unistd.h>

 

  

     2. 用法介绍

         execv会停止执行当前的进程,并且以progname应用进程替换被停止执行的进程,进程ID没有改变。

progname: 被执行的应用程序。

argv: 传递给应用程序的参数列表, 注意,这个数组的第一个参数应该是应用程序名字本身,并且最后一个参数应该为NULL,不参将多个参数合并为一个参数放入数组。

 

      3. 返回值

          如果应用程序正常执行完毕,那么execv是永远不会返回的;当execv在调用进程中返回时,那么这个应用程序应该出错了(可能是程序本身没找到,权限不够...), 此时它的返回值应该是-1,具体的错误代码可以通过全局变量errno查看,还可以通过stderr得到具体的错误描述字符串:

 

       4. 示例

  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3. #include <unistd.h>  
  4. #include <errno.h>  
  5.   
  6.   
  7. main(void)  
  8. {  
  9.   pid_t pid = fork();  
  10.      
  11.   if( pid == 0 ) // this is the child process  
  12.   {  
  13.      execv("/bin/ls", NULL);  
  14.   
  15.      // the program should not reach here, or it means error occurs during execute the ls command.  
  16.      printf("command ls is not found, error code: %d(%s)", errno, strerror(errno);  
  17.   }  
  18. }  

 

 

  

int execl(const char *path, const char *arg, ...);
int execlp(const char *
file, const char *arg, ...);
int execle(const char *
path, const char *arg,
..., char * const
envp[]);
int execv(const char *
path, char *const argv[]);
int execvp(const char *
file, char *const argv[]);


2015-03-05 22:23:02 wangbaochu 阅读数 4819
1. execv()
   1.1函数原型
      #include <unistd.h>
        int execv(const char *progname, char *const argv[]); 

   1.2 用法介绍

        execv会停止执行当前的进程,并且以progname应用进程替换被停止执行的进程,进程ID没有改变

        progname: 被执行的应用程序。

         argv: 传递给应用程序的参数列表, 注意这个数组的第一个参数应该是应用程序名字本身(即argv[0] = progname),并且最后一个参数应该为NULL,不能将多个参数合并为一个参数放入数组。

   1.3 返回值

       如果应用程序正常执行完毕,那么execv是永远不会返回的;当execv在调用进程中返回时,那么这个应用程序应该出错了(可能是程序本身没找到,权限不够等), 此时它的返回值应该是-1,具体的错误代码可以通过全局变量errno查看,还可以通过stderr得到具体的错误描述字符串。

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>


main(void)
{
  pid_t pid = fork();
   
  if( pid == 0 ) // this is the child process
  {
     char *arg1 = "system/bin/sh";
     char *arg2 = "-c";
     char *arg3 = "mkdir mydir";
     char *arg4 = NULL;
     char *arg[] = {arg1, arg2, arg3, arg4};

     execv(arg[0], &arg[0]);

     // the program should not reach here, or it means error occurs during execute the ls command.
     printf("command ls is not found, error code: %d(%s)", errno, strerror(errno);
  }
}
2. wait(等待子进程中断或结束)
    2.1 函数原型
         #include<sys/types.h>
         #include<sys/wait.h>
         pid_t wait (int * status);

   2.2 函数说明:
       (1) wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用 wait()时子进程已经结束,则 wait()会立即返回子进程结束状态值。
       (2) 子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一起返回。状态值status的具体含义请参考 waitpid()。
       (3) 如果执行成功则返回子进程PID,如果有错误发生则返回返回值-1,失败原因存于 errno 中。
       (4) 如果不需要status状态值,则参数 status 可以设成 NULL。

3. waitpid(等待子进程中断或结束)
     3.1 函数原型
          #include<sys/types.h>
          #include<sys/wait.h>
          pid_t waitpid(pid_t pid, int * status, int options);

    3.2 函数说明:
         (1) waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用waitpid()时子进程已经结束,则 waitpid()会立即返回子进程结束状态值。
         (2) 子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一快返回。
         (3) 如果执行成功则返回子进程PID,如果有错误发生则返回返回值-1,失败原因存于 errno 中。
         (4) 如果不在意结束状态值,则参数 status 可以设成 NULL。
         (5) 参数 pid 为欲等待的子进程识别码,其他数值意义如下:
              pid<-1  等待进程组识别码为 pid 绝对值的任何子进程。
              pid=-1  等待任何子进程,相当于 wait()。            
              pid=0   等待进程组识别码与目前进程相同的任何子进程。       
              pid>0   等待任何子进程识别码为 pid 的子进程。
         (6) 参数 option 可以为 0 或下面的 OR 组合:
              WNOHANG 如果没有任何已经结束的子进程则马上返回, 不予以等待。
              WUNTRACED 如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。

         (7) 子进程的结束状态返回后存于 status, 底下有几个宏可判别结束情况:
//Linux <sys/wait.h>
#define WEXITSTATUS(s)  (((s) & 0xff00) >> 8)
#define WCOREDUMP(s)    ((s) & 0x80)
#define WTERMSIG(s)     ((s) & 0x7f)
#define WSTOPSIG(s)     WEXITSTATUS(s)

#define WIFEXITED(s)    (WTERMSIG(s) == 0)
#define WIFSTOPPED(s)   (WTERMSIG(s) == 0x7f)
#define WIFSIGNALED(s)  (WTERMSIG((s)+1) >= 2)
          a. WIFEXITED(status)       如果子进程正常结束则为true。exit(0), exit(-1), 都是正常结束。例如 exit(0), status = 0; exit(-1), status = 0xFF00; exit(-10), status = 0xF600
          b. WEXITSTATUS(status) 取得子进程 exit()返回的结束代码,一般会先用 WIFEXITED 来判断是否正常结束才能使用此宏。
          c. WIFSIGNALED(status)  如果子进程是因为信号而结束则此宏值为真。
          d. WTERMSIG(status)       取得子进程因信号而中止的信号代码,一般会先用 WIFSIGNALED 来判断后才使用此宏。
          e. WIFSTOPPED(status)   如果子进程处于暂停执行情况则此宏值为真。一般只有使用 WUNTRACED 时才会有此情况。
          f. WSTOPSIG(status)       取得引发子进程暂停的信号代码,一般会先用 WIFSTOPPED 来判断后才使用此宏。

     3.3 调用举例
int main() {
    int cpid = fork();
    if (cpid < 0) {
        return -1;
    } else if (cpid == 0) {
        char *arg1 = "system/bin/sh";
        char *arg2 = "-c";
        char *arg3 = "mkdir mydir";
        char *arg4 = NULL;
        char *arg[] = {arg1, arg2, arg3, arg4};

        execv(arg[0], &arg[0]);

        printf("########## exec_command(): error code: %d(%s) ##########", errno, strerror(errno));

        exit(-1);
    } else {
        int status = -1;
        int count = 0;
        while(1)
        {
            //int ret = waitpid(cpid, &status, 0); 如果子进程不结束会一直死等
            int ret = waitpid(cpid, &status, WNOHANG);//WNOHANG 配合while 循环可以实现超时机制
            if (ret) {
                if (WIFEXITED(status)) {
                    //子进程正常结束: exit(任意值无论正负), execv()执行结束没有崩溃
                    //1. execv()执行成功结束: status = 0
                    //2. execv()执行结束,但可能没有执行成功,内部调用了exit(-1): status = 0xFF00
                    //3. 子进程直接调用 exit(-1): status = 0xFF00
                    //4. 子进程直接调用 exit(-10): status = 0xF600
                    if (WEXITSTATUS(status) == 0xFF) {
                        //TODO
                    } else if (WEXITSTATUS(status) == 0xF6) {
                        //TODO
                    } else {
                        //TODO
                    }
                } else {
                    //子进程非正常结束:子进程执行execv()发生崩溃,子进程是因为信号signal而结束
                    //TODO
                }
                break;
            }

            if (++count >= 60) {
                //timeout = 60s
                break;
            }
            sleep(1);
        }
    }

    return 0;
}


2017-02-03 10:35:31 weiyuefei 阅读数 608
1. execv()
   1.1函数原型
      #include <unistd.h>
        int execv(const char *progname, char *const argv[]); 

   1.2 用法介绍

        execv会停止执行当前的进程,并且以progname应用进程替换被停止执行的进程,进程ID没有改变

        progname: 被执行的应用程序。

         argv: 传递给应用程序的参数列表, 注意这个数组的第一个参数应该是应用程序名字本身(即argv[0] = progname),并且最后一个参数应该为NULL,不能将多个参数合并为一个参数放入数组。

   1.3 返回值

       如果应用程序正常执行完毕,那么execv是永远不会返回的;当execv在调用进程中返回时,那么这个应用程序应该出错了(可能是程序本身没找到,权限不够等), 此时它的返回值应该是-1,具体的错误代码可以通过全局变量errno查看,还可以通过stderr得到具体的错误描述字符串。

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

main(void)
{
  pid_t pid = fork();
   
  if( pid == 0 ) // this is the child process
  {
     const char *arg1 = "/bin/sh";
     const char *arg2 = "-c";
     const char *arg3 = "mkdir mydir";
     const char *arg4 = NULL;
     const char *arg[] = {arg1, arg2, arg3, arg4};

     execv(arg[0], (char* const*)&arg[0]);

     // the program should not reach here, or it means error occurs during execute the ls command.
     printf("command ls is not found, error code: %d(%s)\n", errno, strerror(errno));
  }
}

2. wait(等待子进程中断或结束)
    2.1 函数原型
         #include<sys/types.h>
         #include<sys/wait.h>
         pid_t wait (int * status);

   2.2 函数说明:
       (1) wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用 wait()时子进程已经结束,则 wait()会立即返回子进程结束状态值。
       (2) 子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一起返回。状态值status的具体含义请参考 waitpid()。
       (3) 如果执行成功则返回子进程PID,如果有错误发生则返回返回值-1,失败原因存于 errno 中。
       (4) 如果不需要status状态值,则参数 status 可以设成 NULL。

3. waitpid(等待子进程中断或结束)
     3.1 函数原型
          #include<sys/types.h>
          #include<sys/wait.h>
          pid_t waitpid(pid_t pid, int * status, int options);

    3.2 函数说明:
         (1) waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用waitpid()时子进程已经结束,则 waitpid()会立即返回子进程结束状态值。
         (2) 子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一快返回。
         (3) 如果执行成功则返回子进程PID,如果有错误发生则返回返回值-1,失败原因存于 errno 中。
         (4) 如果不在意结束状态值,则参数 status 可以设成 NULL。
         (5) 参数 pid 为欲等待的子进程识别码,其他数值意义如下:
              pid<-1  等待进程组识别码为 pid 绝对值的任何子进程。
              pid=-1  等待任何子进程,相当于 wait()。            
              pid=0   等待进程组识别码与目前进程相同的任何子进程。       
              pid>0   等待任何子进程识别码为 pid 的子进程。
         (6) 参数 option 可以为 0 或下面的 OR 组合:
              WNOHANG 如果没有任何已经结束的子进程则马上返回, 不予以等待。
              WUNTRACED 如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。

         (7) 子进程的结束状态返回后存于 status, 底下有几个宏可判别结束情况:
  1. //Linux <sys/wait.h>  
  2. #define WEXITSTATUS(s)  (((s) & 0xff00) >> 8)  
  3. #define WCOREDUMP(s)    ((s) & 0x80)  
  4. #define WTERMSIG(s)     ((s) & 0x7f)  
  5. #define WSTOPSIG(s)     WEXITSTATUS(s)  
  6.   
  7. #define WIFEXITED(s)    (WTERMSIG(s) == 0)  
  8. #define WIFSTOPPED(s)   (WTERMSIG(s) == 0x7f)  
  9. #define WIFSIGNALED(s)  (WTERMSIG((s)+1) >= 2) 

 a. WIFEXITED(status)       如果子进程正常结束则为true。exit(0), exit(-1), 都是正常结束。例如 exit(0), status = 0; exit(-1), status = 0xFF00; exit(-10), status = 0xF600
          b. WEXITSTATUS(status) 取得子进程 exit()返回的结束代码,一般会先用 WIFEXITED 来判断是否正常结束才能使用此宏。
          c. WIFSIGNALED(status)  如果子进程是因为信号而结束则此宏值为真。
          d. WTERMSIG(status)       取得子进程因信号而中止的信号代码,一般会先用 WIFSIGNALED 来判断后才使用此宏。
          e. WIFSTOPPED(status)   如果子进程处于暂停执行情况则此宏值为真。一般只有使用 WUNTRACED 时才会有此情况。
          f. WSTOPSIG(status)       取得引发子进程暂停的信号代码,一般会先用 WIFSTOPPED 来判断后才使用此宏。

     3.3 调用举例
int main() {  
    int cpid = fork();  
    if (cpid < 0) {  
        return -1;  
    } else if (cpid == 0) {  
        char *arg1 = "system/bin/sh";  
        char *arg2 = "-c";  
        char *arg3 = "mkdir mydir";  
        char *arg4 = NULL;  
        char *arg[] = {arg1, arg2, arg3, arg4};  
  
        execv(arg[0], &arg[0]);  
  
        printf("########## exec_command(): error code: %d(%s) ##########", errno, strerror(errno));  
  
        exit(-1);  
    } else {  
        int status = -1;  
        int count = 0;  
        while(1)  
        {  
            //int ret = waitpid(cpid, &status, 0); 如果子进程不结束会一直死等  
            int ret = waitpid(cpid, &status, WNOHANG);//WNOHANG 配合while 循环可以实现超时机制  
            if (ret) {  
                if (WIFEXITED(status)) {  
                    //子进程正常结束: exit(任意值无论正负), execv()执行结束没有崩溃  
                    //1. execv()执行成功结束: status = 0  
                    //2. execv()执行结束,但可能没有执行成功,内部调用了exit(-1): status = 0xFF00  
                    //3. 子进程直接调用 exit(-1): status = 0xFF00  
                    //4. 子进程直接调用 exit(-10): status = 0xF600  
                    if (WEXITSTATUS(status) == 0xFF) {  
                        //TODO  
                    } else if (WEXITSTATUS(status) == 0xF6) {  
                        //TODO  
                    } else {  
                        //TODO  
                    }  
                } else {  
                    //子进程非正常结束:子进程执行execv()发生崩溃,子进程是因为信号signal而结束  
                    //TODO  
                }  
                break;  
            }  
  
            if (++count >= 60) {  
                //timeout = 60s  
                break;  
            }  
            sleep(1);  
        }  
    }  
  
    return 0;  
} 


2011-11-17 11:14:27 Imbak 阅读数 2051

test1:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    printf("this is in the new process...\n");
    sleep(5);
    printf("I have sleep 5 seconds...\n");
}

test2:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void f(void)
{
   printf("After exec the new process...\n");
}
int main(void)
{
   if(fork()==0)
   {
        execv("./test1",NULL);
   }
   f();
}
test3:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void f(void)
{
   printf("After exec the new process...\n");
}
int main(void)
{ 
	if(fork()==0) 
	{ 
		if(execv("./test1",NULL)<0) 
			f(); 
	}
}


test4:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void f(void)
{
   printf("After exec the new process...\n");
}
int main(void)
{
	system("./test1"); 
	f();
}

test5:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void f(void)
{
   printf("After exec the new process...\n");
}
int main(void)
{
   system("./test1 &");
   f();
}
test2运行结果:

this is in the new process...

After exec the new process...

I have sleep 5 seconds...

test3运行结果:

this is in the new process...

I have sleep 5 seconds...

test4运行结果:

this is in the new process...

I have sleep 5 seconds...

After exec the new process...

test5运行结果:

this is in the new process...

After exec the new process...

I have sleep 5 seconds...


test2:fork出新进程后执行execv执行新的进程,不影响原进程,如果不fork,那么新的进程会取代原进程

test3:execv执行成功后不返回,所以f()执行不到

test4:通过系统调用的方式,test1执行完成后system才有返回值,然后继续执行

test5:后台调用,直接返回,执行结果也test2相同





2017-09-11 15:50:23 haorenxwx 阅读数 1211

“ $()命令替换

可以把一个命令的标准输出插在命令行中的任何位置。
在shell中有两个实现方法:反引号“ 和 $()

echo `echo \$HOSTNAME` //反引号实现
#``已经把\转义成了特殊字符 打印出$HOSTNAME的值
echo $(echo \$HOSTNAME) //$()
# $() \并没有被转义 打印出的是$HOSTNAME
echo $(echo \\$HOSTNAME)
#可以打印出$HOSTNAME的值

例:

date2=`date`
declare -i date_dem=`date --date="$date2" +%s`
#%s也是特殊变量,可以直接在``内保留特殊含义  

(())[]: 数学运算

$(()): 支持+-*/%运算
注意,bash只支持整数运算

${}: 变量替换

可以精准的界定变量的范围

$ echo $AB
#打印变量名为AB的变量值
$ echo ${A}B

参考:
[Linux shell (){},[](()),[ ] (( )) [[ ]]作用与区别]
(http://blog.csdn.net/zzban/article/details/8852655)

linux || && 的用法

阅读数 21

linux {..}用法

阅读数 3

linux的!的用法

阅读数 7

linux的一些用法

阅读数 113

没有更多推荐了,返回首页