這幾天在做測試,用腳本比較容易些。
但是在此過程中遇到一些問題,也引發出對管道的重新思考。
腳本需要實現的功能描述:
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。