【发布时间】:2014-01-30 03:55:40
【问题描述】:
我正在为一个学校项目编写一个自定义 shell,我需要能够通过“execv”函数运行外部命令。我需要我的命令以适当的输出成功运行,或者声明找不到该命令。这是我的代码(带有一些用于调试的 printf() 输出):
/* Create a child process */
pid_t pid = fork();
/* Check if the fork failed */
if (pid >= 0)
{
if (pid == 0)
{
/* This is the child process - see if we need to search for the PATH */
if( strchr( command.args[0], '/' ) == NULL )
{
/* Search the PATH for the program to run */
char fullpath[ sizeof( getenv("PATH") ) ];
strcpy( fullpath, getenv("PATH") );
/* Iterate through all the paths to find the appropriate program */
char* path;
path = strtok( fullpath, colon );
while(path != NULL)
{
char progpath[COMMAND_SIZE];
/* Try the next path */
path = strtok( NULL, colon );
strcpy(progpath, path);
strcat(progpath, "/");
strcat(progpath, command.args[0]);
/* Determine if the command exists */
struct stat st;
if(stat(progpath, &st) == 0)
{
/* File exists. Set the flag and break. */
execv( progpath, command.args );
exit(0);
}
else
{
printf("Not found!\n");
}
}
printf("%s: Command not found!\n", command.args[0]);
}
else
{
...
}
/* Exit the process */
exit(EXIT_FAILURE);
}
else
{
/* This is the parent process - wait for the child command to exit */
waitpid( pid, NULL, 0 );
printf("Done with fork!\n");
}
}
else
{
/* Could not fork! */
printf("%s: %s > Failed to fork command!\n", command.args[0], strerror(errno) );
}
这是输出:
john@myshell:/home/john/project>dir
/usr/local/sbin/dir: Not found!
/usr/local/bin/dir: Not found!
/usr/sbin/dir: Not found!
/usr/bin/dir: Not found!
/sbin/dir: Not found!
/bin/dir: Found!
makefile makefile~ myshell.c myshell.c~ myshell.x
Done with fork!
john@myshell:/home/john/project>foo
/usr/local/sbin/foo: Not found!
/usr/local/bin/foo: Not found!
/usr/sbin/foo: Not found!
/usr/bin/foo: Not found!
/sbin/foo: Not found!
/bin/foo: Not found!
/usr/games/foo: Not found!
Done with fork!
john@myshell:/home/john/project>
已知命令“dir”正在被找到并正确执行。输出很棒。但是,当我使用假的“foo”命令时,我希望它找不到该命令(显然没有),完成“while”循环,然后执行以下“printf”命令。话虽如此,我希望在输出接近尾声时看到以下内容:
foo: Command not found!
我尝试使用布尔值和整数值作为“标志”来确定是否找到了命令。但是,似乎根本没有代码在 while 循环之外运行。如果我删除“exit(0)”,“printf”命令仍然不会运行。我对为什么 while 循环之外的代码似乎根本没有运行感到困惑和困惑。我也不知道这是我分叉方式的问题还是与输出缓冲区有关。
我这样做是不是错误的方式,或者如果找不到命令,我如何确保“找不到命令”消息总是运行一次?
【问题讨论】:
-
我看不到你在哪里打印
"Done with fork!" -
只是快速浏览一下,但在我看来,您似乎并没有处理 second strtok 直接返回 null 的可能性。也许您应该检查并立即中断,而不是尝试对空字符串进行所有这些操作?
-
@woolstar 道歉。我必须在格式化时无意中删除了该行。该行位于“waitpid”调用之后 - 请参阅编辑。谢谢!
-
我会在子路径末尾的
printf之后尝试fflush(stdout)和可能的sleep(1)。 -
@ChrisStratton 感谢您的输入。您是正确的,第二个
strtok调用应该位于语句的末尾(由于这个错误,它完全跳过了第一个标记)。这没有解决问题,但很有帮助!