我明白我应该使用chdir(),但我只需要解释为什么通过系统调用cd shell命令或从子进程调用execvp()不起作用?谢谢!!
我目前正在努力解决这个错误.我正在编写一个shell模拟器,使用fork()来执行使用execvp();的命令.几乎我尝试解析到我的shell的每个命令都工作得很好,除了没有参数的ls.如果我尝试执行ls -lah,一切正常,但是一个简单的ls不会,收到以下错误:
ls: fts_open: No such file or directory
Run Code Online (Sandbox Code Playgroud)
这是我的代码片段:(只是必不可少的)
pid = fork();
if (pid==0)
{
puts("CHILD");
puts(args[0]);
puts(args[1]);
printf("%d\n", strlen(args[1]));
args[2] = NULL;
execvp(args[0], args);
}
else wait(NULL);
puts("BACK TO PARENT");
}
Run Code Online (Sandbox Code Playgroud)
这是ls的输出:
ls
CHILD
ls
0
ls: fts_open: No such file or directory
BACK TO PARENT
Run Code Online (Sandbox Code Playgroud)
如你所见,args [0]包含ls,args [1]为空,因为没有参数,args [1]的长度为0,但我不断收到错误.
有什么想法吗?
编辑:
感谢Jonathan Leffler找到它:(同样,它似乎只是Mac上的一个问题)
关键是args [1]实际上并不是空的,因此,操作系统会尝试打开''文件,显然,该文件不存在,并且看起来不能创建,因为它不是真是个名字.
所以,这就是我所做的:检查args的len [1].如果为0,则将其设置为NULL.(只是释放内存并没有真正帮助)
pid = fork();
if (pid==0)
{
puts("CHILD");
puts(args[0]);
puts(args[1]);
if (strlen(args[1]) == 0)
args[1] = 0;
args[2] = NULL;
execvp(args[0], …Run Code Online (Sandbox Code Playgroud) 我正在编写一个小shell程序,它接受一个命令并执行它.如果用户输入无效命令,则if语句返回-1.如果命令正确则执行命令,但是一旦执行命令,程序就会结束.我做错了什么不会在它之后执行代码行?我用ls和cat命令测试了execvp(command.argv [0],command.argv),所以我很确定它有效.这是我的代码.
int shell(char *cmd_str ){
int commandLength=0;
cmd_t command;
commandLength=make_cmd(cmd_str, command);
cout<< commandLength<<endl;
cout << command.argv[0]<< endl;
if( execvp( command.argv[0], command.argv)==-1)
//if the command it executed nothing runs after this line
{
commandLength=-1;
}else
{
cout<<"work"<<endl;
}
cout<< commandLength<<endl;
return commandLength;
}
Run Code Online (Sandbox Code Playgroud) 我正在用 C 编写一个 shell,但我无法理解execvp(filepath,argv).
如果输入的用户想要ls -a在他们当前的目录中运行......让我们说/home/user1......在所述目录中运行的filepathandargv是ls什么?
请问filepath是哪里的命令将被执行的目录/home/user1或者这将是命令的位置/bin/ls?
我正在编写一个程序,该程序接收命令名称和参数,并且可选地在末尾接收字符串“bg”,如果传递“bg”字符串,我的程序应该在后台执行该命令,如果不在前台,则其参数,这是我的代码:
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
pid_t pid;
int state;
if( (pid=fork())<0) {
perror("\nError in fork");
exit(-1);
}
else if(pid==0) {
if(strcmp(argv[argc-1], "bg") == 0 ){
strcpy(argv[argc-1],"&");
if( (execvp(argv[1], argv)<0)) {
perror("\nError in first execvp");
exit(-1);
}
}
else{
if( (execvp(argv[1], argv+1)<0)) {
perror("\nError en second el execvp");
exit(-1);
}
}
}
wait(&state);
printf("\nMy child %d terminated with state %d\n",pid,state);
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
输入示例:
./myprogram ls -lai bg // in this …Run Code Online (Sandbox Code Playgroud) 我正在尝试做一些非常简单的事情:用C中的execvp调用中的参数填充char**.
这就是我在做的事情:
if(argc >=1)
{
*nargv = "--action";
while(argc--)
{
printf("nargv1 => %s \t argv1 => %s \n", *nargv, *argv);
*++nargv = *argv++;
printf("nargv2 => %s \t argv2 => %s \n", *nargv, *argv);
}
printf("nargv3 => %s \t argv3 => %s \n", *nargv, *argv);
*nargv++ = '\0';
printf("nargv4 => %s \t argv4 => %s \n", *nargv, *argv);
}
Run Code Online (Sandbox Code Playgroud)
输出给了我:
nargv1 => --action argv1 => backup
nargv2 => backup argv2 => --help
nargv1 => backup argv1 => --help
nargv2 => --help …Run Code Online (Sandbox Code Playgroud) 当参数作为 char** 传入时,从字符串向量到 char* 向量再到 char** 是有效的,但转换似乎有问题,我无法找到差异。
有一个更好的方法吗?
vector<string> args;
/* code that correctly parses args from user input */
pid_t kidpid = fork();
if (kidpid < 0)
{
perror("Internal error: cannot fork.");
return -1;
}
else if (kidpid == 0)
{
// I am the child.
vector<char*>argcs;
for(int i=1;i<args.size();i++)
{
char * temp = new char[args.at(i).length()];
for(int k=0;k<args.at(i).length();k++)
{
temp[k] = args.at(i).at(k);
}
argcs.push_back(temp);
}
char** argv = new char*[argcs.size() + 1];
for (int i = 0; i < …Run Code Online (Sandbox Code Playgroud) 即使有警卫人员到位,我的文件仍在尝试两次执行mkdir。
我尝试将ifndef放在另一个c文件中,但仍执行两次
酸碱度
#ifndef P_H
#define P_H
void p1(char* filepath, int m);
#endif
Run Code Online (Sandbox Code Playgroud)
main.c
#include "main.h"// includes ifndef with p1.h inside it
int main(int argc, char *argv[]){
p1("Hi",2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第1版
#include "phase1.h"
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
void p1(char* filepath, int m){
pid_t cpid;
cpid = fork();
if ((cpid = fork()) == -1) {
perror("fork failed");
}
if(cpid > 0){
wait(NULL);
}
else{
char *makeDir[] = {"mkdir", "MyNewDirectory", NULL};
execvp(makeDir[0],makeDir);
}
}
Run Code Online (Sandbox Code Playgroud)
当我执行gcc …
所以我知道exec*函数之后的所有内容都不会被执行(如果exec*调用当然是成功的话).
我想明白为什么会这样?所以我开发了这个小小的程序
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("A program made to understand execvp\n");
char *cmd[4] = {"ls", "-l","file",NULL};
execvp(cmd[0],cmd);
printf("This will not be printed!!\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我所理解的是,bin目录中的可执行命令实际上是可执行程序,因此基本上从我们的程序中调用另一个程序.
而且我确实读到了某个地方
如果成功,exec系统调用不会返回调用程序,因为调用图像丢失.
但这究竟意味着什么,为什么他们不回到调用程序?他们如何回归呢?