2012-05-14 25 views
1

我正在使用一些管道和叉子來執行命令,如Execlp調用沒有TTY的bash

cat file.tar.gz | myprogram -c 「焦油-zvt」 -i 「remoteMachineIp」

但如果我不

myprogram -c 「慶典」 -i 「remoteMachineIp」

bash的是好的,但沒有終端。 沒有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用戶@機器「慶典」在bash自帶的問題,而是突出部分SSH用戶@機器其好的

我怎樣才能用tty調用bash?

感謝

回答

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到管你的程序。如果您的命令是exec ing,那麼這是行不通的。交互式命令需要將其輸入和輸出連接到tty。無論您是否將stdin連接到tty,啓動交互式命令並將其輸出連接到管道可能沒有任何意義。

順便說一句:爲什麼在execlp中使用bash -c <command>而不是sh -c <command>?通過這種方式,您可以在bash上引入不必要的依賴關係,您真正需要的是標準POSIX Bourne shell shexec ing sh -c是通過shell啓動命令的標準方式。這是完成的,例如,通過system()

+0

我正在使用bash -c,因爲項目需要它,所有在套接字中調用的程序都將使用bash。有沒有辦法使用管道和fork與tty? – Lefsler

+0

即使它是'bash'腳本(與普通的'sh'腳本相反),你仍然可以按照啓動東西的標準方式啓動它'sh -c '。如果它是一個Python或Perl或lua腳本或其他任何東西,它就可以工作。 – Celada

+0

「用管道和叉子與tty」?那麼,你的命令的stdio將是一個管道,或者它將是tty。它不能兼而有之。 – Celada

相關問題