Ⅰ 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)