Proceso de Linux 5: Resumen de las funciones de la familia de ejecutivos (execl, execlp, execle, execv, execvp, execvpe) y el uso de exec con fork

Las funciones de la familia exec (execl, execlp, execle, execv, execvp, execvpe) y exec se utilizan con fork

El papel de las funciones de la familia ejecutiva:

Después de crear un nuevo proceso con la función fork, a menudo llamamos a la función exec en el nuevo proceso para ejecutar otro programa.Cuando el proceso llama a la función exec, el proceso se reemplaza por completo con un nuevo programa. Porque llamar a la función exec no crea un nuevo proceso, Por lo tanto, el ID del proceso antes y después no ha cambiado.

caracteristicas:

Ejecute un archivo ejecutable dentro del proceso de llamada. El archivo ejecutable puede ser un archivo binario o cualquier archivo de script ejecutable en Linux

Familia de funciones:

Las familias de funciones ejecutivas son: execl, execlp, execle, execv, execvp, execvpe

Prototipo de función:

#include <unistd.h>
extern char **environ;

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[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);

valor de retorno:

Las funciones de la familia de funciones exec no regresarán después de una ejecución exitosa. Cuando la llamada falla, errno se establecerá y se devolverá -1, y luego continuará ejecutándose desde el punto de llamada del programa original.

Descripción de parámetros:

ruta: el nombre de la ruta del archivo ejecutablearg
: los parámetros del programa ejecutable,El primer parámetro es el nombre del archivo ejecutable, sin una ruta y arg debe terminar con NULL
archivo: si el archivo de parámetros contiene /, se considerará como un nombre de ruta; de lo contrario, buscará archivos ejecutables en los directorios especificados por la variable de entorno PATH.
Los parámetros de la función de la familia exec son extremadamente difíciles de recordar y distinguir, los caracteres en el nombre de la función nos ayudarán:
l: use la lista de parámetros
p: use el nombre del archivo y busque el archivo ejecutable en el entorno PATH
v: primero construya un puntero a cada parámetro Matriz de punteros y luego la dirección de la matriz como parámetro de estas funciones.
e: agregue la matriz envp [], use nuevas variables de entorno en lugar de las variables de entorno del proceso de llamada

La función exac se clasifica en cuatro categorías con l, p, v y e para ilustrar las características de los parámetros.

1. Un tipo de función exac con l (l significa lista), que incluye execl, execlp, execle, y requiere que cada parámetro de línea de comando del nuevo programa se describa como un parámetro separado. Esta lista de parámetros termina con un puntero nulo.

Tome la función execl como ejemplo para ilustrar:

Demostración del caso: el proceso llama a la función execl para ejecutar el programa echoarg.c.
La función execl necesita ejecutar otro programa:

//文件echoarg.c
#include <stdio.h>
int main(int argc,char *argv[])
{
    
    
    int i = 0;
    for(i = 0; i < argc; i++)
    {
    
    
        printf("argv[%d]: %s\n",i,argv[i]); 
    }
    return 0;
}

resultado de la operación:
Inserte la descripción de la imagen aquí

código de función execl:

//文件demo3.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
int main(void)
{
    
    
    printf("before execl\n");
    if(execl("./echoarg","echoarg","abc",NULL) == -1)
    {
    
    
        printf("execl failed!\n");      
    }
    printf("after execl\n");
    return 0;
}

resultado de la operación:
Inserte la descripción de la imagen aquí
Descripción del experimento:
Primero compilamos echoarg.c con gcc para generar el archivo ejecutable echoarg (y lo colocamos en el directorio de ruta actual (.bin o ./)). La función del archivo echoarg es imprimir los parámetros de la línea de comandos. Luego compile execl.cy ejecute el archivo ejecutable execl. Use execl para buscar y ejecutar echoarg, reemplace el proceso principal actual, por lo que "después de execl" no se imprime en la terminal.
Suplemento 1:

whereis ls:打印ls的绝对路径

Inserte la descripción de la imagen aquí

if(execl("/bin/ls","ls",NULL,NULL) == -1)
//修改后打印当前路径所有文件
if(execl("/bin/ls","ls",-l”,NULL) == -1)
//以列表形式显示

Suplemento 2:

whereis date:获取系统的时间的路径

Inserte la descripción de la imagen aquí

 if(execl("/bin/date","date",NULL,NULL) == -1)
 //改写后,获取系统时间

Suplemento 3:

whereis ps: 获取系统进程ID路径

Inserte la descripción de la imagen aquí

if(execl("/bin/ps","ps",NULL,NULL) == -1)
 //改写后,获取系统进程ID

No conozco el camino absolutoEn el caso de que no se encuentre la pantalla (por ejemplo, solo conozca ps):
use:

execlp if(execl("ps","ps",NULL,NULL) == -1)

2. Un tipo de función exac con p, incluyendo execlp, execvp, execvpe, si el archivo de parámetros contiene /, se considerará como el nombre de la ruta; de lo contrario, se buscará en los directorios especificados por la variable de entorno PATH. Archivo ejecutable.
Por ejemplo:
PATH = / bin: / usr / bin

El directorio especificado por la variable de entorno actual:

//环境变量作用:查找需要的可执行文件
echo $PATH  //当前环境变量
pwd  //当前路径
export PATH=$PATH:/home/dazai //当前环境变量所在的当前路径
echo $PATH   //当前环境变量
ls   //显示文件

El verde se puede ejecutar:
Inserte la descripción de la imagen aquí

La función exaclp anterior tiene p, por lo que el archivo ejecutable ps se puede encontrar a través de la variable de entorno PATH

Primero mire la demostración del código de función exacl:

//文件execl_no_path.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
int main(void)
{
    
    
    printf("before execl****\n");
    if(execl("ps","ps","-l",NULL) == -1)
    {
    
    
        printf("execl failed!\n");
    }   
    printf("after execl*****\n");
    return 0;
}

Resultado de la operación: en el
Inserte la descripción de la imagen aquí
ejemplo anterior, debido a que el parámetro no tiene una ruta, execl no puede encontrar el archivo ejecutable.
Veamos otro ejemplo para comparar:

//文件execlp.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execlp(const char *file, const char *arg, ...);
int main(void)
{
    
    
    printf("before execlp****\n");
    if(execlp("ps","ps","-l",NULL) == -1)
    {
    
    
        printf("execlp failed!\n");
    }
    printf("after execlp*****\n");
    return 0;
}

Resultados en ejecución:
Inserte la descripción de la imagen aquí
como se puede ver en los resultados experimentales anteriores, la función exaclp anterior lleva p, por lo que el archivo ejecutable ps se puede encontrar a través de la variable de entorno PATH.

3. Un tipo de función exac con v sin l, incluyendo execv, execvp, execve, primero debe construir una matriz de punteros a cada parámetro y luego usar la dirección de la matriz como parámetro de estas funciones.

Por ejemplo:
como char * arg [], y el último elemento de arg debe ser NULL

char *arg[] = {
    
    “ls”,-l”,NULL}; 

AbajoexecvpFunción como ejemplo:

//文件execvp.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execvp(const char *file, char *const argv[]);
int main(void)
{
    
    
    printf("before execlp****\n");
    char *argv[] = {
    
    "ps","-l",NULL};
    if(execvp("ps",argv) == -1) 
    {
    
    
        printf("execvp failed!\n");     
    }
    printf("after execlp*****\n");
    return 0;
}

resultado de la operación:
Inserte la descripción de la imagen aquí
4. Un tipo de función exac con e, incluidos execle y execvpe, puede pasar un puntero a la matriz de punteros de cadena de entorno.
Parámetros como:

char *env_init[] = {
    
    “AA=aa”,”BB=bb”,NULL}; 

Con e significa que la función toma la matriz envp [] en lugar de usar el entorno actual.

AbajoexecleFunción como ejemplo:

//文件execle.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execle(const char *path, const char *arg,..., char * const envp[]);
char *env_init[] = {
    
    "AA=aa","BB=bb",NULL};
int main(void)
{
    
    
    printf("before execle****\n");
        if(execle("./echoenv","echoenv",NULL,env_init) == -1)
        {
    
    
                printf("execle failed!\n");
        }       
    printf("after execle*****\n");
    return 0;
}

Código de prueba:

//文件echoenv.c
#include <stdio.h>
#include <unistd.h>
extern char** environ;
int main(int argc , char *argv[])
{
    
    
    int i;
    char **ptr;
    for(ptr = environ;*ptr != 0; ptr++)
        printf("%s\n",*ptr);
    return 0;
}

Resultado de la prueba:
Inserte la descripción de la imagen aquí
Primero escribimos un programa que muestra todas las tablas del entorno, llamado echoenv.c, y luego lo compilamos en un archivo ejecutable y lo colocamos en el directorio (./bin o ./). Luego ejecute el archivo ejecutable execle y descubra que las variables de entorno que configuramos efectivamente se pasaron.

5. exec se usa con fork:

Función de realización:
cuando el proceso padre detecta que la entrada es 1, cree un proceso hijo para cambiar el valor de campo del archivo de configuración.

Código de referencia:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
    
    
 pid_t pid;
 int data=10;
 while(1)
 {
    
    
  printf("请输入数据:\n");
  scanf("%d",&data);
  if(data == 1)
  {
    
    
   pid=fork();
   if(pid>0)
   {
    
    
    wait(NULL);//防止变成僵尸进程
   }
   if(pid==0)
   {
    
    
    execl("./changdata","changdata","config.txt",NULL);//执行别的   
   }
  }
  else
  {
    
    
   printf("神码也不做\n");
  }
 }
 return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_40734514/article/details/108993029
Recomendado
Clasificación