重定向符号

重定向符号

应用重定向符号前,要清楚下面的三个问题:

  1. fd 文件描述符是什么
  2. dup、dup2函数的作用
  3. 0、1、2 fd分别是什么文件描述符

第一个问题:点我

第二个问题:

  1. int dup(int oldfd):返回一个新的文件描述符newfd,newfd的值为可用文件描述符的最小值。并且newfd指向oldfd所指向的文件表项
  2. int dup2(int oldfd,int newfd):让传入的新的文件描述符newfd与旧的文件描述符oldfd指向同一文件表项

第三个问题:

名称文件描述符含义对应设备功能说明对应Java
STDIN0标准输入键盘获取执行时所要的输入数据System.in
STDOUT1标准输出显示器输出执行后的输出结果System.out
STDERR2标准错误输出显示器输出执行时的错误信息System.err

命令查询验证

[root@VM-24-5-centos ~]# ll /dev/ | grep std
lrwxrwxrwx 1 root root          15 3月  29 01:56 stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root          15 3月  29 01:56 stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root          15 3月  29 01:56 stdout -> /proc/self/fd/1

通过下图来辅助理解stdin、stdout、stderr(方便理解的简略图,并不完整)

在这里插入图片描述

每个进程可以根据fd获取数据的输入与数据的发出。每个进程至少要有三个fd即:{0, 1, 2}。如果还有其他的文件,在fd表中加入对应项即可。假如在程序中,我们需要获取用户的输入数据,那么就可以依靠fd为0的文件。输出时,具体是输出到屏幕还是其他文件中,取决于我们应用哪一个fd项。

我们还可以通过dup2函数,来将两个fd指向同一个文件。比如:

#include <string.h>
#include <unistd.h>
#include <fcntl.h>
 
int main()
{
	const char *str = "hello world!\n";
 
	dup2(1,3);
	write(3,str,strlen(str));
 
	close(3);
	return 0;
}

执行编译后的可执行文件时,就会在屏幕上显示:hello world!

输入重定向符

<:重定向标准输入符。将stdin标准输入进行重定向。
# 将指定路径下的文件作为标准输入传递给 cat 命令
congqingquan@localhost Desktop % cat < out
Hello world

输出重定向符(最常用)

> 与 >>(默认省略了1):重定向标准输出符。将stdout重定向到指定文件。前者覆盖,后者追加。
congqingquan@localhost Desktop % echo C99 > out
congqingquan@localhost Desktop % cat out
C99
congqingquan@localhost Desktop % echo C99 >> out
congqingquan@localhost Desktop % cat out
C99
C99
congqingquan@localhost Desktop % echo C99 1> out
congqingquan@localhost Desktop % cat out
C99
congqingquan@localhost Desktop %
2> 与 2>>:重定向标准错误输出符。将stderr重定向到指定文件。前者覆盖,后者追加。
public class Test {
    public static void main(String[] args) throws Exception {
    	int a = 1/0;
        System.out.println("Hello world");
    }
}
congqingquan@localhost Desktop % java Test 2> out
congqingquan@localhost Desktop % cat out
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Test.main(Test.java:3)
congqingquan@localhost Desktop % java Test 2>> out
congqingquan@localhost Desktop % cat out
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Test.main(Test.java:3)
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Test.main(Test.java:3)
congqingquan@localhost Desktop % java Test 2> out
congqingquan@localhost Desktop % cat out
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Test.main(Test.java:3)

标准输出符无法应用在程序发生错误时

congqingquan@localhost Desktop % java Test >> out
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Test.main(Test.java:3)
congqingquan@localhost Desktop % cat out
congqingquan@localhost Desktop %
&> 与 &>>:重定向标准输出 & 标准错误输出符。前者覆盖,后者追加。

注意:&>是一个整体,表示重定向标准输出、标准错误输出。

congqingquan@localhost Desktop % echo C99 &> out
congqingquan@localhost Desktop % cat out
C99
congqingquan@localhost Desktop % echo C99 &>> out
congqingquan@localhost Desktop % cat out
C99
C99
congqingquan@localhost Desktop % echo2 C99 &> out
congqingquan@localhost Desktop % cat out
zsh: command not found: echo2
congqingquan@localhost Desktop %
&> 的另一种写法:2>&1
congqingquan@localhost Desktop % echo C99 > out 2>&1
congqingquan@localhost Desktop % cat out
C99
congqingquan@localhost Desktop % echo C99 >> out 2>&1
congqingquan@localhost Desktop % cat out
C99
C99
congqingquan@localhost Desktop % echo2 C99 > out 2>&1
congqingquan@localhost Desktop % cat out
zsh: command not found: echo2
congqingquan@localhost Desktop %
问题1:>后面的&是什么意思?

&表明后面的1为一个fd,而非文件名。如果写成2>1,此时的1代表的是一个文件名,而非一个fd。文件名不等于文件的fd。

验证1:终端已经提示了bad file descriptor

congqingquan@localhost Desktop % cat out
C99
congqingquan@localhost Desktop % echo C992 > out 1>&99999
zsh: 99999: bad file descriptor
congqingquan@localhost Desktop %

验证2:

congqingquan@localhost Desktop % echo2 C99 2> 1
congqingquan@localhost Desktop % cat 1
zsh: command not found: echo2
congqingquan@localhost Desktop %
如何查看文件的fd?

终端1:

[root@VM-24-5-centos home]# tail -f  out
C99

终端2:

[root@VM-24-5-centos ~]# ll /proc/11292/fd/
总用量 0
lrwx------ 1 root root 64 5月  28 21:20 0 -> /dev/pts/1
lrwx------ 1 root root 64 5月  28 21:20 1 -> /dev/pts/1
lrwx------ 1 root root 64 5月  28 21:19 2 -> /dev/pts/1
lr-x------ 1 root root 64 5月  28 21:20 3 -> /home/out
lr-x------ 1 root root 64 5月  28 21:20 4 -> anon_inode:inotify
问题2:为什么2>&1要写到最后?
public class Test {
    public static void main(String[] args) throws Exception {
        System.out.println("Hello world");
 	int a = 1/0;
    }
}

分析下两条命令的执行过程:

congqingquan@localhost Desktop % java Test > out 2>&1
congqingquan@localhost Desktop % cat out
Hello world
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Test.main(Test.java:5)
congqingquan@localhost Desktop %
  1. 起初:fd1 -> 屏幕
  2. > out,fd1 -> out,
  3. 2>&1,fd2 -> fd1 -> out
  4. 执行java Test,程序输出内容写入到fd1文件中,即out文件。发生异常,错误信息写入fd2文件中,即out文件
congqingquan@localhost Desktop % java Test 2>&1 > out
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Test.main(Test.java:5)
congqingquan@localhost Desktop % cat out
Hello world
congqingquan@localhost Desktop %
  1. 起初:fd1 -> 屏幕
  2. 2>&1,fd2 -> fd1 -> 屏幕
  3. >out,fd1 -> out
  4. 执行java Test,程序输出内容写入到fd1,即out文件。发生异常,错误信息写入fd2文件中,即展示在屏幕
分别设定标准输出目的地 与 标准错误输出目的地
congqingquan@localhost Desktop % echo C99 1> out 2>error
congqingquan@localhost Desktop % cat out
C99
congqingquan@localhost Desktop % cat error
congqingquan@localhost Desktop % echo2 C99 1> out 2>error
congqingquan@localhost Desktop % cat out
congqingquan@localhost Desktop % cat error
zsh: command not found: echo2
congqingquan@localhost Desktop %
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值