Ⅰ linux關於管道說法錯誤的是什麼
Linux關於管道 原創
2018-09-14 12:22:41
Gaodes
碼齡5年
關注
管道的概念
管道是Unix中棗鎮蔽最古老的進程間通信的形式。 我們把從一個進程連接到另一個進程的一個數據流稱為一個「管道」 我們通常把是把一個進程的輸出連接或「管接」(經過管道來連接)到另一個進程的輸入。
管道特點
管道是半雙工的,數據只能向一個方向流動;需要雙方通信時,需要建立起兩個管道 只能用於父子進程或者兄弟進程之間(具有親凳州緣關系的進程)進行通信;通常,一個管道由一個進程創建,然後該進程調用fork,此後父、子進程之間就可應用該管道。
pipe函數
包含頭文件<unistd.h> 功能:創建一無名管道 原型
int pipe(int file_descriptor[2]);
參數 file_descriptor:文件描述符數組,其中file_descriptor[0]表示讀端,file_descriptor[1]表示寫端 返回值:成功返回0,失敗返回錯誤代碼
示例代碼:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<string.h>
int main(int argc,char *argv[])
{
int fd[2];
printf("f[0]=%d,f[1]=%d\n",fd[0],fd[1]);
pipe(fd);
printf("f[0]=%d,f[1]=%d\n",fd[0],fd[1]);
char buf[1024]={0};
int fid = fork();
if(fid > 0)
{
read(fd[0],buf,1024);
printf("read data %s\n",buf);
}
else if(fid == 0)
{
write(fd[1],"helloworld",strlen("helloworld"));
}
else
{
perror("fork error");
}
return 0;
}
列印結果
管道讀寫規則:如果試圖從管道寫端旅塌讀取數據,或者向管道讀端寫入數據都將導致錯誤發生 當沒有數據可讀時,read調用就會阻塞,即進程暫停執行,一直等到有數據來到為止。 如果管道的另一端已經被關閉,也就是沒有進程打開這個管道並向它寫數據時,read調用就會阻塞
復制文件描述符p
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
int main()
{
int fd = p(1);
printf("file fd= %d\n",fd);
write(fd,"helloworld",strlen("helloworld"));
return 0;
}
列印結果:
1為輸入到終端
shell管道的實現
原理通過把發的fd[1]寫復制到shell的1(標准輸入),fd[0]復制到shell的2(標准輸出)
以下是代碼:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<signal.h>
int main()
{
int fd[2];
char buf[1024] ={0};
pipe(fd);
int pid = fork();
if(pid > 0)
{
read(fd[0],buf,1024);
printf(buf);
}
else if(pid == 0)
{
p2(fd[1],1);
close(fd[0]);
close(fd[1]);
execlp("ls","ls","-al",NULL);
}
else
{
}
return 0;
}
實現結果:
popen函數
作用:允許一個程序把另外一個程序當作一個新的進程來啟 動,並能對它發送數據或接收數據
FILE* popen(const char *command, const char *open_mode);
command:待運行程序的名字和相應的參數 open_mode:必須是「r」或「w」 如果操作失敗,popen會返回一個空指針
以下代碼:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
int main()
{
FILE *file = popen("ls -al","r");
char buf[1024] = {0};
fread(buf,1,1024,file);
fclose(file);
FILE *wcfile = popen("wc","w");
fwrite(buf,1,strlen(buf),wcfile);
fclose(wcfile);
return 0;
}
代碼結果:
命名管道破裂測試
我們首先要知道命名管道,要讀段和寫段同時開啟,才能向文件讀寫數據。
貼上代碼來理解命名管道的規則
首先是讀端:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<string.h>
#include<fcntl.h>
int main(int argc,char *argv[])
{
printf("open before\n");
int fd = open("/home/gao/tmp/fifo",O_RDONLY);
printf("open after\n");
//休眠5秒,讀端退出
sleep(5);
return 0;
}
接下來是寫端:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<string.h>
#include<fcntl.h>
void handle(int signo)
{
printf("cat signale = %d\n",signo);
}
int main(int argc,char *argv[])
{
signal(SIGPIPE,handle);
printf("open before\n");
int fd = open("/home/gao/tmp/fifo",O_WRONLY);
printf("open after\n");
//命名管道規則,如果寫入讀斷被中斷,寫入會返回-1,並且管道會破裂,產生信號(SIGPIPE)
while(1)
{
int wrsize = write(fd,"helloworld",strlen("helloworld"));
printf("size data:%d\n",wrsize);
sleep(1);
}
}
執行寫端:
它在等待另一端的開啟,才能向裡面寫入數據
此時我們開啟讀端:
馬上可以看到寫段可以寫數據
而執行5秒後,我們可以看到寫的時候返回-1,並且獲取到管道破裂的信息(SIGPIPE)
所以這里就是我們所注意的點,當我們寫客戶端和伺服器進行管道傳輸的時候,如果客戶端一旦退出來,就會使管道破裂,所以我們必須通過捕捉信號,來避免這種事情發生。
Ⅱ 為什麼在Linux中strlwr()不能編譯通過,已經查看過<string.h>,的確在頭文件中沒有
strlwr和strupr都不是標準的C庫函數!有些編譯器不支持很正常,編譯器不支持的,只能自己定義這兩個函數並且用代碼自己去實現它。
個人使用過VC++2010,是可以編譯通過的,證明VC++2010里邊的編譯器支持這兩個函數。
而linux中的GCC編譯器則編譯不通過,證明linux下的GCC編譯器不支持這兩個函數。
Ⅲ C語言strlen求數組長度。為什麼會是這樣,linux下GCC編譯器。
你換台機器就不是58的值了!所謂的固定,是你機器內存情況剛好處在那種狀態下。
你沒有 ,strlen()就會自動去找 位置,這個0位置在什麼位置是不確定的。
strlen(s)函數,從s首地址開始一直統計到 位置,其中有幾個位元組就輸出長度為幾!
#include<stdio.h>
#include<string.h>
voidmain()
{
inti=0;//這里加上這個,你再去試,結果一定會有變化的,原理,自己思考一下吧
charp[]={1,2,3,4,5,66,7,};
charq[]={1,2,3,4};
charr[]={1,2,3,4};
printf("length:%d ",strlen(p));
printf("length2:%d ",strlen(q));
printf("length3:%d ",strlen(r));
}
Ⅳ 在linux命令行下如何將指定的幾行內容寫入到一個文件中
覆蓋型寫法 (文件里原來的內容被覆蓋)
echo "aaa" > a.txt
echo aaa > a.txt
添加型寫法 (新內容添加在原來內容的後面)
echo "aaa" >> a.txt
echo aaa >> a.txt
其中 echo >or>> file,
在 user space 中會賦值到 buf 中為 string+換行符,
傳入到 kernel space 時,buf 為 string+換行符,strlen(buf) = strlen(string) + 1;
.8Normal0
echo命令的功能是在顯示器上顯示一段文字,一般起到一個提示的作用。
該命令的一般格式為: echo [ -n ] 字元串
其中選項n表示輸出文字後不換行;字元串能加引號,也能不加引號。用echo命令輸出加引號的字元串時,將字元串原樣輸出;用echo命令輸出不加引號的字元串時,將字元串中的各個單詞作為字元串輸出,各字元串之間用一個空格分割。
功能說明:顯示文字。
語 法:echo [-ne][字元串]或 echo [--help][--version]
補充說明:echo會將輸入的字元串送往標准輸出。輸出的字元串間以空白字元隔開, 並在最後加上換行號。
參 數:-n 不要在最後自動換行
-e 若字元串中出現以下字元,則特別加以處理,而不會將它當成一般
文字輸出:
\a 發出警告聲;
\b 刪除前一個字元;
\c 最後不加上換行符號;
\f 換行但游標仍舊停留在原來的位置;
\n 換行且游標移至行首;
\r 游標移至行首,但不換行;
\t 插入tab;
\v 與\f相同;
\\ 插入\字元;
\nnn 插入nnn(八進制)所代表的ASCII字元;
–help 顯示幫助
–version 顯示版本信息
ECHO命令是大家都熟悉的DOS批處理命令的一條子命令,但它的一些功能和用法也許你並不是全都知道,不信你瞧:
1. 作為控制批處理命令在執行時是否顯示命令行自身的開關 格式:ECHO [ON|OFF] 如果想關閉「ECHO OFF」命令行自身的顯示,則需要在該命令行前加上「@」。
2. 顯示當前ECHO設置狀態 格式:ECHO
3. 輸出提示信息格式:ECHO信息內容上述是ECHO命令常見的三種用法,也是大家熟悉和會用的,但作為DOS命令淘金者你還應該知道下面的技巧:
4. 關閉DOS命令提示符 在DOS提示符狀態下鍵入ECHO OFF,能夠關閉DOS提示符的顯示使屏幕只留下游標,直至鍵入ECHO ON,提示符才會重新出現。
5. 輸出空行,即相當於輸入一個回車格式:ECHO.值得注意的是命令行中的「.」要緊跟在ECHO後面中間不能有空格,否則「.」將被當作提示信息輸出到屏幕。另外「.」可以用,:;」/[/]+等任一符號替代。在下面的例子中ECHO.輸出的回車,經DOS管道轉向作為TIME命令的輸入,即相當於在TIME命令執行後給出一個回車。所以執行時系統會在顯示當前時間後,自動返回到DOS提示符狀態: C:〉ECHO.|TIME ECHO命令輸出空行的另一個應用實例是:將ECHO.加在自動批處理文件中,使原本在屏幕下方顯示的提示畫面,出現在屏幕上方。
6. 答復命令中的提問格式:ECHO答復語|命令文件名上述格式可以用於簡化一些需要人機對話的命令(如:CHKDSK/F;FORMAT Drive:;del *.*)的操作,它是通過DOS管道命令把ECHO命令輸出的預置答復語作為人機對話命令的輸入。下面的例子就相當於在調用的命令出現人機對話時輸入「Y」回車: C:〉ECHO Y|CHKDSK/F C:〉ECHO Y|DEL A :*.*
7. 建立新文件或增加文件內容 格式:ECHO 文件內容>文件名 ECHO 文件內容>>文件名 例如:C:〉ECHO @ECHO OFF〉AUTOEXEC.BAT建立自動批處理文件 C:〉ECHO C:/CPAV/BOOTSAFE〉〉AUTOEXEC.BAT向自動批處理文件中追加內容 C:TYPE AUTOEXEC.BAT顯示該自動批處理文件 @ECHO OFF C:/CPAV/BOOTSAFE
8. 向列印機輸出列印內容或列印控制碼 格式:ECHO 列印機控制碼>PRN ECHO 列印內容>PRN 下面的例子是向M-1724列印機輸入列印控制碼。<Alt>156是按住Alt鍵在小鍵盤鍵入156,類似情況依此類推: C:〉ECHO 〈Alt〉+156〈Alt〉+42〈Alt〉+116〉PRN(輸入下劃線命令FS*t) C:〉ECHO 〈Alt〉+155@〉PRN(輸入初始化命令ESC@) C:〉ECHO.〉PRN(換行)
9. 使喇叭鳴響 C:〉ECHO ^G 「^G」是用Ctrl+G或Alt+007輸入,輸入多個^G可以產生多聲鳴響。使用方法是直接將其加入批處理文件中或做成批處理文件調用。
10.執行ESC控制序列修改屏幕和鍵盤設置我們知道DOS的設備驅動程序ANSI.SYS提供了一套用來修改屏幕和鍵盤設置的ESC控制序列。如執行下述內容的批處理程序可以把功能鍵F12定義為DOS命令「DIR/W」,並把屏幕顏色修改為白色字元藍色背景。 @ECHO」←[0;134;」DIR/W」;13p @ECHO」←[1;37;44m (註:批處理文件中「←」字元的輸入方法是在編輯狀態下按Alt中小鍵盤上的27)