execve() 和 execvp() 忽略第一个参数
execve() and execvp() are ignoring the first argument
这是作业。
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
int run=1;
while (run) {
int perror;
pid_t pid;
char in[1536];
char para[512]="/bin/";
char *argv[512];
printf("%s..: %s","\x1B[31m","\x1B[37m");
fgets(in,1530,stdin);
char *com = strtok (in," \t\r\n");
char *c2=com;
strcat (para,com);
strcat (para,"[=10=]");
int i=0;
while (com != NULL){
com = strtok (NULL, " \n\r\t");
if (com!=NULL){
argv[i]=com;
i++;
}
}
argv[i]="[=10=]";
if (strcmp(c2, "exit") == 0|strcmp(c2, "quit") == 0){
run=0;
}
else{
if ((pid=fork())==0){ //Child
execvp(para,argv);
}
else{ //Parent
waitpid(pid,&perror,0);
}
}
}
return 0;
}
像 ls
和 pwd
这样的命令在没有参数的情况下工作得很好,但是当我尝试使用参数时,第一个参数被忽略了。下面的示例输出。
$ make
$ ./A1T2
..: ls
A1T2 main.c main.c~ main.c++~ main.c.old Makefile Makefile~
..: pwd
/home/kevin/Documents/COS-222/Assignments/Assignment-1/Task-2
..: mkdir one
one: cannot create directory ‘’: No such file or directory
..: mkdir one two
one: cannot create directory ‘’: No such file or directory
..: ls
: cannot access : No such file or directory
two:
..: exit
kevin@Kevin-MATE:~/Documents/COS-222/Assignments/Assignment-1/Task-2$ make
./A1T2
..: ls
A1T2 main.c main.c~ main.c++~ main.c.old Makefile Makefile~ two
..: echo hello world
world
..: exit
$
将params
放入argv[0]
并将argv
中的所有内容向下移动并调用:
execvp (argv[0], argv);
注意:execvp()的第一个参数不是字符串,而是指向字符串的指针,就像argv[]数组中的所有条目一样,argv[]数组以最后一个条目结束NULL 的,而不是 '\0'
以下代码:
compiles cleanly,
performs the desired function.
用户输入行'ls'将打印当前目录中的所有文件名。
用户输入行 'ls -la' 将打印当前目录中所有文件名的长版本。
但是,用户输入 'ls *' 行将失败,并显示有关找不到文件的消息。 IE。没有执行 'glob'ing。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
enum
{
MAX_PARAMETERS = 512,
MAX_PGM_NAME_LEN = 512,
MAX_USER_INPUT_LEN =1563
};
int main(void)
{
int run=1;
while (run)
{
int status;
pid_t pid;
char in[MAX_USER_INPUT_LEN];
char para[MAX_PGM_NAME_LEN]="/bin/";
char *argv[MAX_PARAMETERS] = {'[=11=]'};
int i = 1; // index into argv[] list
// change some terminal screen characteristic
printf("%s..: %s","\x1B[31m","\x1B[37m");
printf( "enter program name to be executed and any parameters\n separated by space, tab or newline\n");
fgets(in,MAX_USER_INPUT_LEN,stdin);
char *pgmName = strtok (in," \t\r\n");
if( NULL == pgmName )
{ // then strtok failed
perror( "strtok failed" );
exit( EXIT_FAILURE );
}
// implied else, strtok successful
printf( "program to execute: %s\n", pgmName);
char *c2=pgmName;
strcat( para, pgmName);
argv[0] = para;
printf( "argv[0] = %s\n", argv[0]);
char * parameter = NULL;
while (NULL != (parameter = strtok(NULL, " \n\r\t") ) )
{
printf( "argv[%d] = %s\n", i, parameter);
argv[i]=parameter;
i++;
}
argv[i]=NULL; // terminate the parameter list
if ( (strcmp(c2, "exit") == 0) | (strcmp(c2, "quit") == 0) )
{
run=0;
}
else
{
pid=fork();
if (-1 == pid)
{ // then fork failed
perror( "fork() failed");
exit( EXIT_FAILURE );
}
// implied else, fork successful
if( 0 == pid)
{ //Child
execvp(para,argv);
exit( EXIT_FAILURE ); // should never get here
}
else
{ //Parent
waitpid(pid,&status,0);
}
}
}
return 0;
}
我建议您使用 main(argc, argv)
接收用于启动代码的命令行参数,然后调用 execvp(argv[1], &argv[1]);
这将简单地传递您在启动代码时在命令行上提供的所需参数,因此,如果您使用...启动代码...
yourcode ls -l -b
execvp()
方法将接收 "ls" 作为第一个参数和“-l”和“-b”作为附加参数。
记住,不要重复代码,并始终提供注释。
这是作业。
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
int run=1;
while (run) {
int perror;
pid_t pid;
char in[1536];
char para[512]="/bin/";
char *argv[512];
printf("%s..: %s","\x1B[31m","\x1B[37m");
fgets(in,1530,stdin);
char *com = strtok (in," \t\r\n");
char *c2=com;
strcat (para,com);
strcat (para,"[=10=]");
int i=0;
while (com != NULL){
com = strtok (NULL, " \n\r\t");
if (com!=NULL){
argv[i]=com;
i++;
}
}
argv[i]="[=10=]";
if (strcmp(c2, "exit") == 0|strcmp(c2, "quit") == 0){
run=0;
}
else{
if ((pid=fork())==0){ //Child
execvp(para,argv);
}
else{ //Parent
waitpid(pid,&perror,0);
}
}
}
return 0;
}
像 ls
和 pwd
这样的命令在没有参数的情况下工作得很好,但是当我尝试使用参数时,第一个参数被忽略了。下面的示例输出。
$ make
$ ./A1T2
..: ls
A1T2 main.c main.c~ main.c++~ main.c.old Makefile Makefile~
..: pwd
/home/kevin/Documents/COS-222/Assignments/Assignment-1/Task-2
..: mkdir one
one: cannot create directory ‘’: No such file or directory
..: mkdir one two
one: cannot create directory ‘’: No such file or directory
..: ls
: cannot access : No such file or directory
two:
..: exit
kevin@Kevin-MATE:~/Documents/COS-222/Assignments/Assignment-1/Task-2$ make
./A1T2
..: ls
A1T2 main.c main.c~ main.c++~ main.c.old Makefile Makefile~ two
..: echo hello world
world
..: exit
$
将params
放入argv[0]
并将argv
中的所有内容向下移动并调用:
execvp (argv[0], argv);
注意:execvp()的第一个参数不是字符串,而是指向字符串的指针,就像argv[]数组中的所有条目一样,argv[]数组以最后一个条目结束NULL 的,而不是 '\0'
以下代码:
compiles cleanly,
performs the desired function.
用户输入行'ls'将打印当前目录中的所有文件名。
用户输入行 'ls -la' 将打印当前目录中所有文件名的长版本。
但是,用户输入 'ls *' 行将失败,并显示有关找不到文件的消息。 IE。没有执行 'glob'ing。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
enum
{
MAX_PARAMETERS = 512,
MAX_PGM_NAME_LEN = 512,
MAX_USER_INPUT_LEN =1563
};
int main(void)
{
int run=1;
while (run)
{
int status;
pid_t pid;
char in[MAX_USER_INPUT_LEN];
char para[MAX_PGM_NAME_LEN]="/bin/";
char *argv[MAX_PARAMETERS] = {'[=11=]'};
int i = 1; // index into argv[] list
// change some terminal screen characteristic
printf("%s..: %s","\x1B[31m","\x1B[37m");
printf( "enter program name to be executed and any parameters\n separated by space, tab or newline\n");
fgets(in,MAX_USER_INPUT_LEN,stdin);
char *pgmName = strtok (in," \t\r\n");
if( NULL == pgmName )
{ // then strtok failed
perror( "strtok failed" );
exit( EXIT_FAILURE );
}
// implied else, strtok successful
printf( "program to execute: %s\n", pgmName);
char *c2=pgmName;
strcat( para, pgmName);
argv[0] = para;
printf( "argv[0] = %s\n", argv[0]);
char * parameter = NULL;
while (NULL != (parameter = strtok(NULL, " \n\r\t") ) )
{
printf( "argv[%d] = %s\n", i, parameter);
argv[i]=parameter;
i++;
}
argv[i]=NULL; // terminate the parameter list
if ( (strcmp(c2, "exit") == 0) | (strcmp(c2, "quit") == 0) )
{
run=0;
}
else
{
pid=fork();
if (-1 == pid)
{ // then fork failed
perror( "fork() failed");
exit( EXIT_FAILURE );
}
// implied else, fork successful
if( 0 == pid)
{ //Child
execvp(para,argv);
exit( EXIT_FAILURE ); // should never get here
}
else
{ //Parent
waitpid(pid,&status,0);
}
}
}
return 0;
}
我建议您使用 main(argc, argv)
接收用于启动代码的命令行参数,然后调用 execvp(argv[1], &argv[1]);
这将简单地传递您在启动代码时在命令行上提供的所需参数,因此,如果您使用...启动代码...
yourcode ls -l -b
execvp()
方法将接收 "ls" 作为第一个参数和“-l”和“-b”作为附加参数。
记住,不要重复代码,并始终提供注释。