[英]Why does execvp() failed when executing more than 1 command in C?
我正在編寫一個程序,它將從文件名 cmdfile.txt 中讀取命令列表並在終端中執行它們。
cmdfile.txt 包含:
whoami
cal 4 2020
echo The time is:
date
我面臨的問題是,當文件僅包含 1 個命令行時,程序可以正常運行。 但是,當文件包含多於 1 個命令行時,該命令無法執行或產生未知命令。 以下是我正在進行的工作代碼:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdbool.h>
#include <string.h>
void parse(char *line, char **argv)
{
while (*line != '\0') { /* if not the end of line ....... */
while (*line == ' ' || *line == '\t' || *line == '\n')
*line++ = '\0'; /* replace white spaces with 0 */
*argv++ = line; /* save the argument position */
while (*line != '\0' && *line != ' ' &&
*line != '\t' && *line != '\n')
line++; /* skip the argument until ... */
}
*argv = '\0'; /* mark the end of argument list */
}
void execute(char **argv)
{
pid_t pid;
int status;
pid = fork();
if (pid < 0) { /* fork a child process */
perror("The error for fork() is: ");
exit(1);
}
else if (pid == 0) { /* for the child process: */
if (execvp(*argv, argv) < 0) { /* execute the command */
perror("The error is: ");
exit(1);
}
}
else { /* for the parent: */
while (wait(&status) != pid) /* wait for completion */
;
}
}
void main(void)
{
char line[1024]; /* the input line */
char *argv[64]; /* the command line argument */
bool running = 1;
FILE *fp = fopen("cmdfile.txt", "r");
if(fp == NULL)
{
perror("Unable to open file!");
exit(1);
}
while (fgets(line, 1024, fp)) { /* repeat until done .... */
strtok(line, "\n");
parse(line, argv);
execute(argv);
}
}
我的第一個猜測是因為 fgets 由於新行的分離而沒有像我預期的那樣運行? 我試圖將行打印到終端以跟蹤錯誤,但我不知道程序出了什么問題。 誰能幫我指出我犯的錯誤?
運行上述代碼時我的 output:
The error is: : No such file or directory
cal: not a valid year 2020
The time is:
The error is: : No such file or directory
The time is:
The error is: : No such file or directory
The error is: : No such file or directory
cmdfile.txt
文件來自一台 Windows 的機器,在沒有翻譯行尾的情況下被復制到一台 Linux 的機器上。 因此,每一行都以 CRLF — "\r\n"
結尾。 您的代碼小心地將'\n'
替換為 null 字節,但會在字符串中留下'\r'
。 當您將"whoami\r"
傳遞給execvp()
時,它找不到命令; 它會找到"whoami"
,但不會找到另一個。 cal
似乎也不喜歡以\r
結尾的數字。 等等。 ( echo
命令不關心'\r'
。)
有很多方法可以修復它。 在您的代碼上下文中,最簡單的方法是將main()
循環中的strtok()
行更改為:
strtok(line, "\r\n");
字符串中字符的順序無關緊要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.