在提供的代码片段中,我正在寻求有关如何增强其功能的指导。具体来说,我想实现一个功能,当用户输入内置命令以外的命令(例如“ls”)时,shell 应作为子进程执行系统命令。此外,我的目标是在这些子进程中建立一个环境条目“parent=/linShell”。此条目旨在传达有关父 shell 工作目录的信息。如果您能将此增强功能合并到现有代码中,我将不胜感激。
void execute_command(char* command, int background) {
pid_t pid = fork();
if (pid < 0) {
perror("Fork failed");
exit(EXIT_FAILURE);
} else if (pid == 0) {
// Child process
if (background) {
setsid(); // Run the process in a new session to detach it from the terminal
}
char* argv[] = { "/bin/sh", "-c", command, NULL };
execv(argv[0], argv);
// If execv fails
perror("Execv failed");
exit(EXIT_FAILURE);
} else {
// Parent process
if (!background) {
waitpid(pid, NULL, 0); // Wait for the child process to complete
} else {
// Print the background process ID (PID)
printf("The command runs in background with ID: %d\n", pid);
}
}
}
我想实现一个功能,当用户输入内置命令以外的命令(例如“ls”)时,shell 应作为子进程执行系统命令。
您似乎在这方面取得了进展。正常的方法是创建一个子进程,并在其中使用
fork()
系列函数之一来运行请求的命令。但是,您没有运行所请求的命令。您正在运行一个 shell,并要求它运行该命令。目前尚不清楚这样做会带来什么好处,因为您的 shell 需要能够执行直接运行外部命令的所有操作(命令行解析、重定向(如果支持)、扩展等),它还需要能够do 运行内置命令。
此外,您可能不想将子设备与终端分离。您可能希望将其放在与父 shell 不同的进程组中,但即使将后台进程移动到其自己的会话也是不正常的。请查看 exec
来控制当前会话中的哪些进程可以访问终端。
我的目标是在这些子进程中建立一个环境条目“parent=/linShell”。此条目旨在传达有关父 shell 工作目录的信息。
你说“工作目录”,但你似乎提供了一个固定的字符串。 shell 的工作目录(通常)是动态的。它的初始值不是预先确定的,用户可以通过(在 Bourne 系列和 Csh 系列 shell 中)命令更改它。
tcsetpgrp()
但这是一个次要问题。主要问题似乎是如何进入流程环境,这很简单。那些不采用显式环境的
cd
系列函数会将调用者的环境转发到新的进程映像。这意味着您所要做的就是在调用 exec
之前将所需的变量添加到分叉子项的环境中。例如:
execv()