Administrator
发布于 2021-04-06 / 160 阅读
0
0

linux 重定向

下面是linux使用重定向>>配置hosts的例子

cat >> /etc/hosts << EOF
192.168.141.131 deployment
EOF

文件描述符 0 1 2

在Linux系统中0 1 2是一个文件描述符
0表示标准输入
1表示标准输出
2表示标准错误输出

名称代码操作符Java中表示Linux 下文件描述符(Debian 为例)
标准输入(stdin)0< 或 <<System.in/dev/stdin -> /proc/self/fd/0 -> /dev/pts/0
标准输出(stdout)1>、>> 或 1>、1>>System.out/dev/stdout -> /proc/self/fd/1 -> /dev/pts/0
标准错误输出(stderr)22> 或 2>>System.err/dev/stderr -> /proc/self/fd/2 -> /dev/pts/0

>>>都属于输出重定向,<属于输入重定向。
&>>&可以将stderr错误信息标准输出stdout重定向输出
>可以将stdout标准输出信息重定向输出

cat file表示连接文件然后打印到标准输出设备上,读取的文件会输出到stdout上,单纯执行cat表示连接标准输入流stdin(即键盘输入),然后读取键盘输入,然后输出到stdout。

cat > file,表示读取标准输入流stdin(键盘输入),然后将标准输出stdout重定向>到文件file中,一般配合分界符使用即<< EOF,也就是一开始讲到的例子;而cat &> file,表示读取stdout和stderr输出然后重定向到file中。

stdin

符号作用
命令 < 文件将文件作为命令的标准输入
命令 << 分界符从标准输入中读入,直到遇到分界符停止
命令 < 文件1 >文件2将文件1作为命令的标准输入并将标准输出到文件2

stdout、stderr

符号作用
命令 > 文件将标准输出重定向到文件中(清除原有文件中的数据)
命令 2> 文件将错误输出重定向到文件中(清除原有文件中的数据)
2和>之间不能有空格,它们是一个整体。
命令 >> 文件将标准输出重定向到文件中(在原有的内容后追加)
命令 2>> 文件将错误输出重定向到文件中(在原有内容后面追加)
命令 >> 文件 2>&1

命令 &>> 文件
将标准输出和错误输出共同写入文件(在原有内容后追加)

注意:&>> 将标准输出和错误输出共同追加写入文件。
2>&1是正确用法,2>1是把stderr流重定向到新建文件1中, 2&>1是把stdout和stderr流重定向到新建文件1中。
windows执行&>会报错,是不允许的。

简单测试的例子

下面是实际在linux命令行的测试结果:
[root@iZwz9exe2jul8fhhtuhxfgZ ~]]# lll
-bash: lll: command not found   // 由于Linux没有lll这个命令所以会把stderr输出流输出到屏幕上。
[root@iZwz9exe2jul8fhhtuhxfgZ ~]]# lll > test
-bash: lll: command not found  // 由于这个是错误信息,所以不能使用标准输出stdout>将信息重定向到test文件中,所以stderr输出仍然是指向屏幕。
[root@iZwz9exe2jul8fhhtuhxfgZ ~]]# lll &> test  // 使用&>重定向后错误信息没有输出到控制台了,表示错误信息正确重定向到了test文件
[root@iZwz9exe2jul8fhhtuhxfgZ ~]]# cat test
-bash: lll: command not found  //通过cat命令确实看到了  保存的错误信息

考虑一条日常部署jar包的指令

nohup java -jar app.jar >>log 2>&1 &

为什么2>&1一定要写到>>log后面,才表示标准错误输出和标准输出都定向到log中?
我们不妨把1和2都理解是一个指针,然后来看上面的语句就是这样的:

  1. 本来1----->屏幕 (1指向屏幕)
  2. 执行>log后, 1----->log (1指向log)
  3. 执行2>&1后, 2----->1 (2指向1,而1指向log,因此2也指向了log)

如果放到前面:

nohup java -jar app.jar 2>&1 >log &

  1. 本来1----->屏幕 (1指向屏幕)
  2. 执行2>&1后, 2----->1 (2指向1,而1指向屏幕,因此2也指向了屏幕)
  3. 执行>log后, 1----->log (1指向log,2还是指向屏幕)
    所以这就不是我们想要的结果。

简单做个试验测试下上面的想法

public class Test {
    public static void main(String[] args) {
        System.out.println("out1");
        System.err.println("error1");
    }
}

javac编译后运行下面指令:

java Test 2>&1 > log

你会在终端上看到只输出了"error1",log文件中则只有"out1"。

原文链接:https://blog.csdn.net/zhaominpro/article/details/82630528


评论