我正在用 C 语言开发 shell 命令,但在使用命令 execv 时遇到问题。我在 main 中有一个 do while(1),所以它应该是一个无限循环,但是如果我引入/bin/ls 作为命令,提示符会显示文件和文件夹,然后它会停止。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX_LENGTH 256
#define DEFAULT_STRING_LENGTH 256
#define MAX_PARAMETERS 16
void initParams(char *** params);
void read_command(char *** params);
void freeParams(char *** params);
void type_prompt();
int comprobarSalir(char ***cadena);
int main(){
int salir = 0;
do{
char ** params;
type_prompt();
fflush(stdout);
initParams (& params);
read_command (& params);
salir = comprobarSalir(& params);
if(comprobarSalir(¶ms)==0){
if(execv(params[0], params) == -1){
printf("%s,%s",params[0],params[1]);
printf("Error al ejecutar el comando ' %s': %s\n", params [0], strerror(errno));
freeParams (& params);
}
}
}while(1);
}
void read_command(char *** args) {
char input [256], *substr;
int n = 0;
fgets(input , sizeof(input), stdin);
input[strlen(input) -1] = '\0';
substr = strtok(input , " ");
if (substr != NULL)
memcpy ((* args)[n], substr , strlen(substr));
else
(*args)[n] = NULL;
n++;
while ((* args)[n-1] != NULL) {
substr = strtok(NULL , " ");
if (substr != NULL)
memcpy ((* args)[n], substr , strlen(substr));
else
(*args)[n] = NULL;
n++;
}
}
void freeParams(char *** params){
int i;
char ** parameter;
for (i=0; i<MAX_PARAMETERS; i++) {
parameter = ((* params) +i);
if (* parameter != NULL) free(* parameter);
}
free(* params);
*params = NULL;
}
void initParams(char *** params) {
int i, j;
char ** parameter;
*params = (char **) malloc(sizeof(parameter) * MAX_PARAMETERS);
for (i = 0; i<MAX_PARAMETERS; i++) {
parameter = (* params) + i;
*parameter = (char*) malloc(DEFAULT_STRING_LENGTH);
for (j = 0; j<DEFAULT_STRING_LENGTH; j++) *((* parameter)+j) = '\0';
}
}
void type_prompt(){
char cwd[MAX_LENGTH];
getcwd(cwd, sizeof(cwd));
printf("%s$ ",cwd);
}
int comprobarSalir(char ***cadena){
int salir = 0;
char* exit = "exit";
if(***cadena==*exit){
salir = 1231;
}
return salir;
}
execv
用不同的程序替换调用它的进程。
由于当前进程正在运行一个不同的程序(ls
),当然它的循环将不再继续。
如果你想让一个进程在调用execv
后继续运行,那么你需要使用fork()
创建一个子进程;检查您是 parent 还是 child ,并仅在 child 中调用 execv
。此时,如果您希望父级等待ls
的复制完成,您可以在父级中使用wait()
来这样做,并确定是否 child 成功或失败。
我是一名优秀的程序员,十分优秀!