【问题标题】:Segmentation fault using execvp in c shell [duplicate]在c shell中使用execvp进行分段错误[重复]
【发布时间】:2026-02-15 06:20:03
【问题描述】:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h> 
#include <string.h>

void main(){
char *cmd;
pid_t pid;
while (1) {
printf("$ ");
fgets(cmd,1000,stdin);
if (pid = fork() == -1) {
exit(1);
}
else if (pid == 0){
execvp(cmd,&cmd);
}
else{
int status;
wait(&status);
}
}
}

我正在制作一个执行命令的简单外壳,但是当我在提示符下输入命令时,我不断收到分段错误。这是最简单的版本,仅适用于像“ls”这样的单参数命令

【问题讨论】:

  • 欢迎来到 Stack Overflow!听起来您可能需要学习如何使用调试器来逐步执行代码。使用好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏差在哪里。如果您要进行任何编程,这是必不可少的工具。进一步阅读:How to debug small programs.
  • 是什么让你决定阅读最多1000chars?
  • 这个pid = fork() == -1 并没有像你想象的那样做(详情请看这里:en.cppreference.com/w/c/language/operator_precedence)。
  • 那么 1000 的最大值部分是实验性的。当程序正常运行时,我会以更通用的方式工作

标签: c shell exec fgets


【解决方案1】:

对于您的问题,在您的代码中,

 fgets(cmd,1000,stdin);

cmd 未初始化。它没有指向有效的内存。访问无效内存调用undefined behavior

您需要先将内存分配给cmd,然后才能使用它。或者,您可以考虑将cmd 设为一个数组,例如char cmd[1000] = {0};,以避免需要自己分配内存。

那么,execvp(cmd,&amp;cmd); 不太对,不是你想的那样。阅读man page 以获得更好的理解。

也就是说,对于托管环境,void main() 至少应该是 int main(void) 以符合标准。

【讨论】:

  • 但我有char* cmd;,如果我看到这个,它会初始化指针
  • @JimmySamoladas 很好,它定义了cmd,并没有初始化它,更不用说是一个有效的了。
  • 我之前尝试过 char 数组,但我收到有关要求 const char* 的 execvp 参数的错误,我给了 const char*[1000]
  • @JimmySamoladas 我不认为您正确使用了execvp(),请阅读我的答案中链接的手册页。
  • 这让我很困惑。我希望它在没有参数的情况下运行,只是命令名称,所以我不知道在execvp 的第二个参数中放入什么我试过强制转换 (const char*) NULL 但这似乎不对