如何阻止第一个子进程的执行?
How to stop the first child process from being executed?
目的:设计一个 linux shell,它显示从用户那里获取输入的提示,创建一个新进程来执行该命令,然后终止/退出该进程。这是我的代码
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
using namespace std;
string cmd; //global string so cmd copied to child to execute
void HandleAsParent(){
cout<<"Linux Shell 1.0n";
string s;
while (!exitflag) {
cout<<"myShell>";
getline(cin,cmd); //Take user input
fork();
wait(NULL);
}
}
void HandleAsChild(){
cout<<"Executing";
system(cmd.c_str());
}
int main() {
pid_t p = fork();
if(p != 0){
HandleAsParent(); //This is parent process
}
else {
HandleAsChild(); //This is child process
}
}
问题是,由于 main 中的第一个 fork(( 调用,
myShell>正在执行
在程序运行时显示在第一行,而不仅仅是
我的壳牌>
. 我能够理解为什么会发生这种情况,但无法弄清楚如何阻止第一个子进程的执行。 请向我建议解决方法/解决方案。
编辑1:这是我的作业之一(用于学习UNIX过程( 问题,并明确指出该程序"提示 用户,解析该命令,然后使用 子进程">
正如我已经猜到的,system()
可能使用了fork()
、exec()
和wait()
的组合。出于好奇,我在谷歌上搜索源代码,并在 woboq.org 上找到了一个:glibc/sysdeps/posix/system.c。
考虑到这一点,使用system()
,所需的子进程"免费提供"。所以,我得到了这个最小的样本:
#include <iostream>
void callCmd(const std::string &cmd)
{
system(cmd.c_str());
}
int main()
{
std::cout << "My Linux Shell 1.0n"
<< "Type exit[Enter] to exit.n";
for (;;) {
std::cout << "> ";
std::string input; std::getline(std::cin, input);
if (input == "exit") return 0;
callCmd(input);
}
}
在Windows 10上的cygwin上编译和测试:
$ g++ -std=c++11 -o mycroShell mycroShell.cc
$ ./mycroShell
My Linux Shell 1.0
Type exit[Enter] to exit.
> echo "Hello"
Hello
> exit
$
运行此内容后,callCmd()
中的system()
调用可以替换为fork()
/exec()
/wait()
,而无需更改任何其他内容。
简化版本可能如下所示:
#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void callCmd(const std::string &input)
{
// the pre-processing: split the input into command and arguments
std::string cmdArgs = input;
std::vector<char*> args;
char *cmd = &cmdArgs[0];
args.push_back(cmd);
for (char *c = cmd; *c; ++c) {
if (*c == ' ') {
*c = ' '; args.push_back(c + 1);
}
}
args.push_back(nullptr); // append terminator
// simple replacement of system() (not that sophisticated)
int ret = fork();
if (ret < 0) { // failure
std::cerr << "Failed to execute '" << cmd << "'!n";
} else if (ret == 0) { // child
execvp(cmd, args.data());
} else { // parent
waitpid(ret, nullptr, 0);
}
}
int main()
{
std::cout << "My Linux Shell 1.1n"
<< "Type exit[Enter] to exit.n";
for (;;) {
std::cout << "> ";
std::string input; std::getline(std::cin, input);
if (input == "exit") return 0;
callCmd(input);
}
}
再次在Windows 10上的cygwin上编译和测试:
$ g++ -std=c++11 -o mycroShell mycroShell.cc
$ ./mycroShell
My Linux Shell 1.1
Type exit[Enter] to exit.
> /usr/bin/echo "Hello"
"Hello"
> exit
$
笔记:
恕我直言,其中最棘手的部分是为
execvp
准备一个适当的参数向量。我也尝试了
echo "Hello"
,它奏效了。这让我有点惊讶echo
因为它是一个 bash 内置命令。我假设它找到了/usr/bin/echo
并使用它以及我的上述输出。错误处理相当糟糕 - 应该针对严重的应用程序进行扩展。
相关文章:
- 终止 QProcess 不会终止子进程
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 子进程更新共享 mmap 内存,但父进程没有更改
- 使用 waitpid 时等待子进程终止
- 使用重定向标准处理子进程中的 kbhit
- 由 JOB 中的进程启动的子进程是否可以将 JOB 属性设置为脱离作业?
- 是否可以将子进程的 stdout 重定向到父进程中的另一个文件?
- kill() 总是返回 0(成功),即使在子进程已经结束之后?
- 父进程和子进程之间的 POSIX 信号量
- 检测到由于操作系统内存不足而导致子进程终止
- 使用system()创建独立的子进程
- 从stdin读取时子进程挂起(fork/dup2竞争条件)
- 在 Bash 脚本中处理来自子进程的信号
- Qt C++ - 如何成功将数据传递给子进程?
- C++ 窗口本地系统模拟在子进程中失败
- 将类型化数组写入子进程 stdin 无法正常工作
- 将 nodejs 脚本作为子进程执行(而不是从其他脚本执行)
- 子进程在分叉和执行后变得失效
- 等待执行不可执行脚本的子进程
- 在 java 代码中执行子进程时缺少输出