管道實現交互

這幾天在做測試,用腳本比較容易些。

但是在此過程中遇到一些問題,也引發出對管道的重新思考。微笑


腳本需要實現的功能描述:

1,循環上100次

2,每次,都需要運行一個服務器上的程序(就叫J程序吧)微笑

                都需要輸入密碼


問題:

這裏需要從腳本里往J裏輸入密碼,這裏我不會。

我的問題集中在,怎麼往標準輸入中寫入數據。

好,我在腳本中這樣寫的:

“password" >/dev/fd/0

但shell把“password" 當做命令來處理。我想它可能是,用exec來執行“password" 的。難過

然後,echo “password" >/dev/fd/0

還是不行,直接打印出來了。大哭


===================================================================================


1,驗證爲什麼不行

我想原因是什麼?shell那麼常用,不應該不會有這麼一個東東的。

接着我寫了一個c語言的程序,來驗證,echo “password" >/dev/fd/0爲什麼沒寫到子程序的標準輸入裏。

#include <stdio.h>
#include <unistd.h>
void main()
{
        pid_t   pid;
        char s[10] = {0};
        if ((pid = fork()) == 0) {
                // child
                scanf ("%s", s);
                printf ("%s\n", s);
                while (1);
        } else {
                // parent
                scanf ("%s", s);
                printf ("-----%s\n", s);
                while (1);
        }
}
這裏得到的啓示是:父子程序對fd其實也存在搶佔的,如果父進程先得到標準輸入,那麼他會把標準輸入隊列裏的東東拿乾淨。。。原來如此。。。偷笑


2,尋找另外的出路

管道,試了

echo "password" | J
成功了。


3,爲什麼

要弄懂爲什麼就要確定問題是什麼:

①什麼是管道

這是在網上找的管道的實現

#include <stdio.h>
#include <unistd.h>

int fd[2];

char *argv[] = {"ls", (char*)0};
char *envp[] = {"PATH=/bin", 0};
char *argv2[] = {"wc", (char*)0};
char *envp2[] = {"PATH=/bin", 0};

void run_ls()
{
	dup2(fd[1], 1);
	close (fd[0]);
	close (fd[1]);
	execve("/bin/ls", argv, envp);
}

void run_wc()
{
	dup2(fd[0], 0);
	close (fd[0]);
	close (fd[1]);
	execve("/usr/bin/wc", argv2, envp2);
}

int main()
{
	pipe(fd);
	if (fork() == 0) {
		run_ls(); 
	} else {
		run_wc(); // 如果標準輸入沒有東東的話,就會阻塞。所以不用考慮父子進程誰先執行。
	}
	return 0;
}

解決了。


4,後續:

後面還有很多內容要學習,比如高級一點的expect等,高級一點的進程間通信的概念。

最近有很多東西,要學習,這裏的後續放到有空的時候吧。


5,重定向也能實現往進程中傳數據的功能

echo "1 2 3" > file.txt

wc < file.txt

注意,這裏重定向的話,一定是命令或者執行程序寫在前面。不能寫成: file.txt > wc。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章