今日命令:
more filenamen //分屏显示filename 内容
od -c filename //使用二进制形式查看文件内容
dup和dup2也是两个非常有用的调用,它们的作用都是用来复制一个文件的描述符。它们经常用来重定向进程的stdin、stdout和stderr。这两个函数的原形如下:
#include
int dup( int oldfd );
int dup2( int oldfd, int targetfd );
利用函数dup,我们可以复制一个描述符。传给该函数一个既有的描述符,它就会返回一个新的描述符,这个新的描述符是传给它的描述符的拷贝。这意味着,这两个描述符共享同一个数据结构。例如,如果我们对一个文件描述符执行lseek操作,得到的第一个文件的位置和第二个是一样的。下面是用来说明dup函数使用方法的代码片段:
int fd1, fd2;
...
fd2 = dup( fd1 );
dup2函数跟dup函数相似,但dup2函数允许调用者规定一个有效描述符和目标描述符的id。在使用dup2的时候若第二个参数的描述符targetfd已经打开则现将其关闭, dup2函数成功返回时,目标描述符(dup2函数的第二个参数)将变成源描述符(dup2函数的第一个参数)的复制品,换句话说,两个文件描述符现在都指向同一个文件,并且是函数第一个参数指向的文件。下面我们用一段代码加以说明:
int oldfd;
oldfd = open("app_log", (O_RDWR | O_CREATE), 0644 );
dup2( oldfd, 1 );
close( oldfd );
#include
#include
#include
int main()
{
int pfds[2];
if ( pipe(pfds) == 0 ) {
if ( fork() == 0 ) {
close(1);
dup2( pfds[1], 1 );
close( pfds[0] );
execlp( "ls", "ls", "-l", NULL );
} else {
close(0);
dup2( pfds[0], 0 );
close( pfds[1] );
execlp( "wc", "wc", "-l", NULL );
}
return 0;
}
//复制文件描述符并向文件写数据
#include
#include
#include
#include
#include
void main()
{
int fd,newfd;
char *bufFD="Advanced Programming! write by fd\n";
char *bufNewFD="Advanced Programming! write by NewFD\n";
fd = open("test.txt",O_RDWR|O_CREAT,0644);
if(fd==-1)
{
printf("open file error%m\n");
exit(-1);
}
//开始复制了
newfd = dup(fd);
//使用fd写
write(fd,bufFD,strlen(bufFD));
close(fd);
//使用newfd写
write(newfd,bufNewFD,strlen(bufNewFD));
if(close(newfd)==-1)
{
printf("close error\n");
}
exit(0);
}
实现简单cat命令:实现的是无论输入多少参数都能将其转化为标准输出输出出来。
#include "io.h"
#include
#include
#include
#include
#include
int main(int argc, char * argv[])
{
int fd_in = STDIN_FILENO;
int fd_out = STDOUT_FILENO;
int i;
for(i = 1; i < argc; i ++)
{ //写上fro循环是为了无论输入几个命令行参数,都能够将其转换为标准输出输出出来
fd_in = open(argv[i],O_RDONLY);
if(fd_in < 0){
perror("open error");
continue;
}
copy(fd_in,fd_out);
close(fd_in);
}
if(argc == 1)
{
copy(fd_in,fd_out);
}
return 0;
}
io.c文件
#include "io.h"
#include
#include
#include
#include
#include
#include
#define BUFFER_LEN 1024
void copy(int fdin, int fdout)
{
char buffer[BUFFER_LEN];
ssize_t size;
while(( size = read(fdin, buffer, BUFFER_LEN )) > 0)
{
printf("current %ld\n",lseek(fdin,0L,SEEK_CUR));
if( write( fdout, buffer, size) != size)
{
fprintf(stderr,"write error: %s\n",strerror(errno));
exit(1);
}
}
if(size < 0)
{
fprintf(stderr, "read error: %s\n",strerror(errno));
exit(1);
}
}
io.h头文件
#ifndef __IO_H
#define __IO_H
extern void copy(int fdin, int fdout);
#endif
使用dup函数,打造升级版cat命令:
#include "io.h"
#include
#include
#include
#include
#include
/*
*bin/mcat + iotec.txt (+为输入重定向)
*bin/mcat - iotec.txt(-为输出重定向)
*/
int main(int argc, char * argv[])
{
int fd_in = STDIN_FILENO;
int fd_out = STDOUT_FILENO;
int flag = 0;
int i;
for(i = 1; i < argc; i ++)
{ //写上fro循环是为了无论输入几个命令行参数,都能够将其转换为标准输出输出出来
if(!strcmp("+", argv[i]))
{
fd_in = open(argv[++i],O_RDONLY);
if(fd_in < 0)
{
perror("open error");
}
//将标准输入重定向到文件
if(dup2(fd_in, STDIN_FILENO) != STDIN_FILENO)
{
perror("dup2 error!");
exit(1);
}
close(fd_in);
}
else if(!strcmp("-",argv[i]))
{
fd_out = open(argv[++i], O_WRONLY | O_CREAT | O_TRUNC, 0777);
if(fd_out < 0)
{
perror("open fd_out error!");
exit(1);
}
//将标准输出重定向到文件
if(dup2(fd_out, STDOUT_FILENO) != STDOUT_FILENO)
{
perror("dup2 error");
exit(1);
}
}
else
{
flag = 1;;
fd_in = open(argv[i], O_RDONLY);
if(fd_in < 0)
{
perror("open error!");
exit(1);
}
if(dup2(fd_in ,STDIN_FILENO) != STDIN_FILENO)
{
perror("dup2 error");
exit(1);
}
copy(STDIN_FILENO,STDOUT_FILENO);
close(fd_in);
}
}
if(!flag)
{
copy(STDIN_FILENO, STDOUT_FILENO);
}
return 0;
}