Shell 输入输出重定向与其他符号¶
- Linux 一切皆文件,字符设备、块设备文件都在/dev 目录中
- 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 |
举例¶
-
>
: 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
-
>>
: 与>
相同,但是 append 追加写usts@usts1060:~$ echo "hello world" >> a.txt usts@usts1060:~$ cat a.txt world hello world
-
&>
或>&
: 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
-
将 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
-
<
: 输入重定向wc -l
: 统计行数usts@usts1060:~$ cat a.txt hello hello hello hello usts@usts1060:~$ wc -l < a.txt 4
管道¶
|
: 管道,上一条命令的输出,作为下一条命令的输入,只连接 stdout|&
: 除了 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
其他符号¶
-
&&
: and, 上一条命令执行成功后,才执行下一条命令 -
||
: 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
-
&
: 放在命令最后,使任务在后台执行,与 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 &
查看目录中文件数量¶
- 不包含子目录中的文件数量,
ls -l [dir] | grep "^-" | wc -l
- 包含子目录中的文件 数量,
ls -lR [dir] | grep "^-" | wc -l
- 目录中的文件夹数量,不含子目录,
ls -l [dir] | grep "^d" | wc -l
- 目录中的文件夹数量,包含子目录,
ls -lR [dir] | grep "^d" | wc -l
-R, --recursive list subdirectories recursively
^-
匹配文件,^d
匹配目录man wc
print newline, word, and byte counts for each filewc -l
统计输出信息的行数