我正在使用一些管道和分叉来执行像
这样的命令cat file.tar.gz | myprogram -c“tar -zvt”-i“remoteMachineIp”
但如果我这样做
myprogram -c“bash”-i“remoteMachineIp”
bash还可以,但没有tty。 没有tty如果我调用vim命令就会打开vi messed。
如何使用tty在execlp上调用bash。
代码示例
if(cm->pid2==0){ //pipe and fork to send data to my execlp
close(cm->fout[0]);
dup2(cm->fout[1], 1);
execlp("bash", "bash", "-c", command.c_str(), NULL); // command is mycommand so is bash -c "bash"
}
else{
close(cm->fout[1]);
while((size=read(cm->fout[0], buffer, 2000)) > 0){
cm->message->send(buffer, size); //send the data to my program
}
//Close it and send the return code
问题是execlp将bash返回给我,但没有tty 如果我调用ssh user @ machine“bash”,bash会出现问题,但jut ssh user @ machine可以
如何用tty调用bash?
由于
答案 0 :(得分:1)
我想您担心的是,您启动的命令会从其父级(stdin
)继承myprogram
,而其父级stdin
是从cat file.tar.gz
接受数据的管道。您希望运行一个被迫从tty读取数据的子项,而不是继承的stdin
管道。
您可以打开/dev/tty
以获取对tty的引用。如果没有tty,它将失败。例如:
close(0);
open("/dev/tty", O_RDWR);
/* The file descriptor returned by open should be 0 */
但是,我注意到您将子命令的stdout
重定向到您的程序的管道。如果您exec
的命令是交互式的,那么这将不起作用。交互式命令需要将其输入和输出连接到tty。无论是否将stdin
连接到tty,启动交互式命令并将其输出连接到管道可能没有任何意义。
顺便说一下:为什么在bash -c <command>
中使用sh -c <command>
代替execlp
?这样,您就会在bash
引入不必要的依赖,而您真正需要的只是标准的POSIX bourne shell sh
。 exec
通过sh -c
是通过shell启动命令的标准方法。这就是system()
所做的。