Linux下重定向exec以及dup说明

重定向

在linux中经常会用到重定向功能如下一个简单的例子

linux:[~/xx]
$ echo "123" > akfile
linux:[~/xx]
$ cat akfile
123
linux:[~/xx
$ echo "123" >>  akfile
linux:[~/xx]
$ cat akfile
123
123

  1. >将echo的输出重定向到akfile的输入达到往文件写的目的,而不输出显示当前界面
  2. >>则是追加写
  3. > 实际上是1> 的简写,注意没有空格,默认标准输出1的输出到文件而不是当前终端,> 永远是标准输出的简写。

特殊设备

cat /dev/null > akfile //即可将akfile清空

设备描述符

在linux下每个文件都有一个描述符去想关联系起来,其值没有含义只是一个对应关系,但规定这三个值有特殊含义。
0 标准输入
1 标准输出
2 标准错误

举例

ls -la > akfile 2>&1

&1 :表示引用标准输出,可以想象成标准输出将要输出到的那个设备文件(/dev/tty  /dev/ttyS0)。
2>&1 :表示吧2标准错误的输出地方和1一样,重定向2
> :默认是指1的重定向也就是标准输出重定向到akfile
所以整个意思是ls的内容全部打印到akfile,同时错误也打印到1对应的里面也就是指向的akfile

上面还能简写
ls &> akfile
表示覆盖方式 把1和2都指向akfile。

exec使用

我们知道012是默认使用掉的后面的只要没占用的我们就能用
可以用,exec为绑定重定向

ls /proc/self/fd -la   查看fd使用情况
exec 4> akfile   把4作为akfile的fd
echo "234234" >&4 注意没有空格,吧echo 打到4指向的文件里

exec 1>&4 可以把1重定向到4指向的文件从而打印到文件
exec 4>&-  关闭fd,腾出来,/proc/self/fd下面就没有4这个fd了

重定向相关的函数

dup

 #include <unistd.h>
 #include <fcntl.h>        
 #include <unistd.h>
 //根据oldfd 复制一个新的fd(当前进程最小可以fd),newfd 和oldfd 指向的文件相同。
newfd = dup(oldfd );
if (newfd == -1 && errno != EBADF) {
    
    
     /* Handle unexpected dup() error */
 }


if (dup2(oldfd, newfd) == -1) {
    
    
               /* Handle dup2() error */
 }
/*
dup2则你用一个希望值来复制oldfd
在newfd中指定的数字。如果文件描述符newfd以前是打开的,那么它在被重用之前将被静默关闭。
如果oldfd不是一个有效的文件描述符,那么调用失败,并且newfd没有关闭。
如果oldfd是一个有效的文件描述符,并且newfd的值与oldfd相同,则dup2()不执行任何操作,并返回newfd。
*/

setvbuf

设置fd 文件内容缓存模式

 _IONBF unbuffered
 _IOLBF line buffered
 _IOFBF fully buffered
 setvbuf(stream, NULL, _IOLBF, 0);
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int main()
{
    
    
	int fd_ser =  open("/dev/ttyS0", O_WRONLY);
	int ret;
	printf("1");//默认打进缓存,不会立即显示
   	ret = setvbuf(stdout, NULL, _IONBF, 0);
	perror("heihei");
	printf("\n setvbuf ret:%d[%s]\n",ret,strerror(errno));
	ret = dup2(fd_ser, 1);//1指向的动向复制fd_ser指向的也就吧1输出到串口
	printf("\n dup2 ret:%d[%s]\n",ret,strerror(errno));
   	printf("2asdfasd\n");
	sleep(1);
   	return 0;

}

1 进程退出前会调用fflush吧缓存里面的东西刷出去。
2 这里举这个例子是想说明在glibc下你在setvbuf前打印到缓存的东西没关系setvbuf依旧能工作,但是在uclibc下这个就不能了会报错,setvbuf前不能有任何流相关的操作
附图

  1. uClibc’s setvbuf is more restrictive about when it can be called than glibc’s
    is. The standards specify that setvbuf must occur before any other operations
    take place on the stream.

Guess you like

Origin blog.csdn.net/weixin_41884251/article/details/121480379