Skip to content

Shell 输入输出重定向与其他符号

  1. Linux 一切皆文件,字符设备、块设备文件都在/dev 目录中
  2. File Descriptor 为文件描述符,缩写 fd
usts@usts1060:~$ ll /dev/fd/
total 0
dr-x------ 2 usts usts  0 Jan 25 16:21 ./
dr-xr-xr-x 9 usts usts  0 Jan 25 16:21 ../
lrwx------ 1 usts usts 64 Jan 25 16:21 0 -> /dev/pts/0
lrwx------ 1 usts usts 64 Jan 25 16:21 1 -> /dev/pts/0
lrwx------ 1 usts usts 64 Jan 25 16:21 2 -> /dev/pts/0
lr-x------ 1 usts usts 64 Jan 25 16:21 3 -> /proc/14015/fd/
usts@usts1060:~$ ll /dev/std*
lrwxrwxrwx 1 root root 15 Jan 25 13:19 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jan 25 13:19 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jan 25 13:19 /dev/stdout -> /proc/self/fd/1
文件描述符 文件名 类型 硬件
0 stdin 标准输入文件 键盘
1 stdout 标准输出文件 显示器
2 stderr 标准错误输出文件 显示器

重定向

stdout 与 stderr 重定向

输出重定向是指命令的结果不再输出到显示器上,而是输出到其它地方,一般是文件中

重定向类型 使用符号 作用
stdout command > file 以覆盖的方式,把 command 的正确输出结果输出到文件中
stdout command >> file 以追加的方式,把 command 的正确输出结果输出到文件中
stderr command 2> file 以覆盖的方式,把 command 的错误信息输出到文件中
stderr command 2>> file 以追加的方式,把 command 的错误信息输出到文件中
stdout and stderr command > file 2>&1 以覆盖的方式,把正确输出和错误信息同时保存到同一个文件中
stdout and stderr command >> file 2>&1 以追加的方式,把正确输出和错误信息同时保存到同一个文件中
stdout and stderr command > file1 2> file2 以覆盖的方式,把正确的输出结果输出到 file1 中,把错误信息输出到 file2 中
stdout and stderr command >> file1 2>> file2 以追加的方式,把正确的输出结果输出到 file1 中,把错误信息输出到 file2 中

stdin 重定向

输入重定向就是改变输入的方向,不再使用键盘作为命令输入的来源,而是使用文件作为命令的输入

符号 说明
command < file 将 file 中的内容作为 command 的输入
command < file1 > file2 将 file1 作为 command 的输入,并将 command 的处理结果输出到 file2

举例

  1. >: stdout redirection,标准输出重定向,overwrite 覆盖写

    usts@usts1060:~$ touch a.txt
    usts@usts1060:~$ cat a.txt
    usts@usts1060:~$ echo "hello" > a.txt
    usts@usts1060:~$ cat a.txt
    hello
    usts@usts1060:~$ echo "world" > a.txt
    usts@usts1060:~$ cat a.txt
    world
    
  2. >>: 与>相同,但是 append 追加写

    usts@usts1060:~$ echo "hello world" >> a.txt
    usts@usts1060:~$ cat a.txt
    world
    hello world
    
  3. &>>&: stdout, stderr redirection,更偏向于使用&>,等价于> [file] 2>&1

    &>>等价于>> [file] 2>&1

    usts@usts1060:~$ stderr
    stderr: command not found
    usts@usts1060:~$ stderr &> a.txt
    usts@usts1060:~$ stderr >& a.txt
    usts@usts1060:~$ stderr > a.txt 2>&1
    usts@usts1060:~$ cat a.txt
    stderr: command not found
    
  4. 将 stdout 和 stderr 分别输出到不同文件中

    usts@usts1060:~$ ls -l a.txt
    -rw-rw-r-- 1 usts usts 24 Jan 25 21:06 a.txt
    usts@usts1060:~$ ls -l b.txt
    ls: cannot access 'b.txt': No such file or directory
    usts@usts1060:~$ ls -l a.txt b.txt > stdout.log 2> stderr.log
    usts@usts1060:~$ cat stdout.log
    -rw-rw-r-- 1 usts usts 24 Jan 25 21:06 a.txt
    usts@usts1060:~$ cat stderr.log
    ls: cannot access 'b.txt': No such file or directory
    
  5. <: 输入重定向

    wc -l: 统计行数

    usts@usts1060:~$ cat a.txt
    hello
    hello
    hello
    hello
    usts@usts1060:~$ wc -l < a.txt
    4
    

管道

  1. |: 管道,上一条命令的输出,作为下一条命令的输入,只连接 stdout
  2. |&: 除了 stdout 外,还连接了 stderr,是2>&1 |的缩写
usts@usts1060:~$ ps -ef | grep "python"
root       949     1  0 13:19 ?        00:00:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
root      1012     1  0 13:19 ?        00:00:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
usts     16919  9849  0 16:31 pts/0    00:00:00 grep --color=auto python

其他符号

  1. &&: and, 上一条命令执行成功后,才执行下一条命令

  2. ||: or,上一条命令执行失败后,才执行下一条命令

    usts@usts1060:~$ ls && ls
    Desktop  Documents  Downloads  linkchen  Music  Pictures  Public  Templates  Videos
    Desktop  Documents  Downloads  linkchen  Music  Pictures  Public  Templates  Videos
    usts@usts1060:~$ ls || ls
    Desktop  Documents  Downloads  linkchen  Music  Pictures  Public  Templates  Videos
    usts@usts1060:~$ lll || ls
    
    Command 'lll' not found, did you mean:
    
      command 'lli' from deb llvm-runtime
      command 'dll' from deb brickos
      command 'llc' from deb llvm
      command 'llt' from deb storebackup
    
    Try: sudo apt install <deb name>
    
    Desktop  Documents  Downloads  linkchen  Music  Pictures  Public  Templates  Videos
    
  3. &: 放在命令最后,使任务在后台执行,与 nohup 一起使用,结合 stdout, stderr 重定向保存程序运行日志

    nohup python -u train.py > ./models/log/train4.log 2>&1 &
    nohup tensorboard --logdir=runs --bind_all &> /var/log/tensorboard.log &
    nohup jupyter notebook &> /var/log/jupyter.log &
    

查看目录中文件数量

  1. 不包含子目录中的文件数量, ls -l [dir] | grep "^-" | wc -l
  2. 包含子目录中的文件 数量,ls -lR [dir] | grep "^-" | wc -l
  3. 目录中的文件夹数量,不含子目录,ls -l [dir] | grep "^d" | wc -l
  4. 目录中的文件夹数量,包含子目录,ls -lR [dir] | grep "^d" | wc -l
  5. -R, --recursive list subdirectories recursively
  6. ^- 匹配文件,^d 匹配目录
  7. man wc print newline, word, and byte counts for each file
  8. wc -l 统计输出信息的行数

参考阅读

  1. GNU Bash Manual Redirections
  2. GNU Bash Manual Pipelines
  3. GNU Bash Manual List of Commands

Comments