简体   繁体   English

如何使forkpty / execvp()正确处理重定向和其他bash行为?

[英]How to get forkpty/execvp() to properly handle redirection and other bash-isms?

I've got a GUI C++ program that takes a shell command from the user, calls forkpty() and execvp() to execute that command in a child process, while the parent (GUI) process reads the child process's stdout/stderr output and displays it in the GUI. 我有一个GUI C ++程序,该程序从用户处接收shell命令,调用forkpty()和execvp()在子进程中执行该命令,而父(GUI)进程读取子进程的stdout / stderr输出,在GUI中显示它。

This all works nicely (under Linux and MacOS/X). 这一切都很好(在Linux和MacOS / X下)。 For example, if the user enters "ls -l /foo", the GUI will display the contents of the /foo folder. 例如,如果用户输入“ ls -l / foo”,则GUI将显示/ foo文件夹的内容。

However, bash niceties like output redirection aren't handled. 但是,不处理诸如输出重定向之类的bash细节。 For example, if the user enters "echo bar > /foo/bar.txt", the child process will output the text "bar > /foo/bar.txt", instead of writing the text "bar" to the file "/foo/bar.txt". 例如,如果用户输入“ echo bar> /foo/bar.txt”,则子进程将输出文本“ bar> /foo/bar.txt”,而不是将文本“ bar”写入文件“ /” foo / bar.txt”。

Presumably this is because execvp() is running the executable command "echo" directly, instead of running /bin/bash and handing it the user's command to massage/preprocess. 大概是因为execvp()直接运行可执行命令“ echo”,而不是运行/ bin / bash并将用户命令交给它进行按摩/预处理。

My question is, what is the correct child process invocation to use, in order to make the system behave exactly as if the user had typed in his string at the bash prompt? 我的问题是,为了使系统完全像用户在bash提示符下键入其字符串一样,使用什么正确的子进程调用? I tried wrapping the user's command with a /bin/bash invocation, like this: /bin/bash -c the_string_the_user_entered, but that didn't seem to work. 我尝试使用/ bin / bash调用包装用户的命令,如下所示:/ bin / bash -c the_string_the_user_entered,但这似乎不起作用。 Any hints? 有什么提示吗?

ps Just calling system() isn't a good option, since it would cause my GUI to block until the child process exits, and some child processes may not exit for a long time (if ever!) ps仅仅调用system()并不是一个好的选择,因为它将导致我的GUI阻塞,直到子进程退出,并且某些子进程可能不会长时间退出(如果有的话!)。

If you want the shell to do the I/O redirection, you need to invoke the shell so it does the I/O redirection. 如果要外壳程序执行I / O重定向,则需要调用外壳程序,以便它执行I / O重定向。

char *args[4];
args[0] = "bash";
args[1] = "-c";
args[2] = ...string containing command line with I/O redirection...;
args[4] = 0;

execv("/bin/bash", args);

Note the change from execvp() to execv() ; 注意从execvp()execv()的更改; you know where the shell is - at least, I gave it an absolute path - so the path-search is not relevant any more. 您知道外壳的位置-至少,我给了它绝对路径-因此,路径搜索不再相关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM