【问题标题】:Execlp call bash without TTY没有 TTY 的 Execlp 调用 bash
【发布时间】:2012-05-14 15:00:22
【问题描述】:

我正在使用一些管道和叉子来执行类似的命令

cat 文件.tar.gz | myprogram -c "tar -zvt" -i "remoteMachineIp"

如果我这样做了

myprogram -c "bash" -i "remoteMachineIp"

bash 没问题,但没有 tty。 如果没有 tty,如果我调用 vim 命令,它会打开 vi 混乱。

如何使用 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 会出现问题,但只要 ssh user@machine 就可以了

如何使用 tty 调用 bash?

谢谢

【问题讨论】:

    标签: c++ bash sockets ssh tty


    【解决方案1】:

    我猜您担心的是您启动的命令从其父级 (myprogram) 继承 stdin,而其父级的 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 重定向到您的程序的管道。如果你是execing 的命令是交互式的,这将不起作用。交互式命令需要将其输入和输出都连接到 tty。无论您是否将 stdin 连接到 tty,启动一个将其输出连接到管道的交互式命令可能没有任何意义。

    顺便问一下:为什么在execlp 中使用bash -c <command> 而不是sh -c <command>?这样你就引入了对bash 的不必要的依赖,你真正需要的只是标准的POSIX bourne shell shexecing 到 sh -c 是通过 shell 启动命令的标准方式。例如,system() 就是这样做的。

    【讨论】:

    • 我正在使用 bash -c 因为项目需要它,套接字中调用的所有程序都将使用 bash。有没有办法在 tty 中使用 pipe 和 fork?
    • 即使它是一个bash 脚本(而不是通用的sh 脚本),您仍然可以按照启动事物的标准方式使用sh -c <the-script> 启动它。如果它是 Python 或 Perl 或 lua 脚本或其他任何东西,这也适用。
    • “使用管道和叉子与 tty”?好吧,您的命令的标准输入输出要么是管道,要么是 tty。不能两者兼有。
    • 如何使用 tty 执行我的 bash?
    • 我已经在答案中说过:open("/dev/tty", O_whatever);dup2() 将结果指向您想要定向到 tty 的任何文件描述符(0 表示标准输入,1 表示标准输出,2 表示标准错误)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    相关资源
    最近更新 更多