Shell输入输出重定向和管道命令

输入/输出重定向

command > file 将输出重定向到file
1
2
3
4
5
6
7
8
9
➜  command touch log.txt
➜ command ls
log.txt
➜ command cat log.txt
➜ command ps > log.txt
➜ command cat log.txt
PID TTY TIME CMD
17928 pts/0 00:00:01 zsh
21688 pts/0 00:00:00 ps
command < file 将输入重定向到file
1
2
3
4
➜  command wc -l command.txt
1 command.txt
➜ command wc -l < command.txt
1
command >> file 将输出以追加的方式重定向到file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
➜  command ls
log.txt
➜ command cat log.txt
PID TTY TIME CMD
17928 pts/0 00:00:01 zsh
21688 pts/0 00:00:00 ps
➜ command ps >> log.txt
➜ command cat log.txt
PID TTY TIME CMD
17928 pts/0 00:00:01 zsh
21688 pts/0 00:00:00 ps
PID TTY TIME CMD
17928 pts/0 00:00:01 zsh
21821 pts/0 00:00:00 ps
<< tag 将输入重定向到一个交互式Shell脚本或程序
1
2
3
4
command << delimiter
document
delimiter
# 作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command
1
2
3
4
5
6
➜  command wc -l << EOF
heredoc> hello
heredoc> world
heredoc> !
heredoc> EOF
3
n >& m 将输出文件 m 和 n 合并。
  • 一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

    • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
    • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
    • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息
  • command > file 将 stdout 重定向到 file

1
2
➜  command > file 2>&1
# 将 stdout 和 stderr 合并后重定向到 file
n <& m 将输入文件 m 和 n 合并。
  • command < file 将stdin 重定向到 file
1
2
➜  command < file1 2<&0
# 将 stdin 和 stderr 合并后重定向到 file

管道命令

command_1; command_2; command_3; 顺序执行多条命令
1
2
➜  command touch file.txt; ls;
file.txt
command & 表示任务在后台执行
1
2
3
4
5
6
7
8
➜  test_code cat csdn_spider.py
#!/usr/bin/env python
# coding=utf-8
。。。
➜ test_code python csdn_spider.py &
[1] 19020
➜ test_code ps -aux | grep python
root 15076 0.3 0.9 60224 17444 ? SN 2018 155:29 python3 csdn_spider.py
command_1 && command_2 表示前一条命令执行成功后才会执行下一条命令
  • 前一条命令执行成功

    1
    2
    3
    4
    5
    6
    ➜  test_code ls
    hello.py tensorboard.py test.py test.py.tar.gz
    ➜ test_code cat file && rm file
    cat: file: No such file or directory
    ➜ test_code ls
    hello.py tensorboard.py test.py test.py.tar.gz
  • 前一条命令执行失败

1
2
3
4
5
6
7
8
9
➜  test_code ls
hello.py tensorboard.py test.py test.py.tar.gz
➜ test_code cat hello.py && rm hello.py
#!/usr/bin/env python
# coding=utf-8

print('hello')
➜ test_code ls
tensorboard.py test.py test.py.tar.gz
command_1 | command_2 表示管道,上一条命令的输出作为下一条命令的参数
1
2
3
4
5
6
➜  test_code ps
PID TTY TIME CMD
17928 pts/0 00:00:00 zsh
19839 pts/0 00:00:00 ps
➜ test_code ps | grep zsh
17928 pts/0 00:00:00 zsh
command_1 || command_2 表示上一条命令执行失败后,才会执行下一条命令
  • 上一条命令执行失败

    1
    2
    3
    4
    5
    ➜  command ls
    ➜ command cat file.txt || touch file.txt
    cat: file.txt: No such file or directory
    ➜ command ls
    file.txt
  • 上一条命令执行成功

    1
    2
    3
    4
    5
    ➜  command ls
    file.txt
    ➜ command cat file.txt || rm file.txt
    ➜ command ls
    file.txt

其他运算符

(command_1; command_2; command_3) 执行圆括号内一组命令
1
2
3
4
5
6
7
8
➜  command ls
command.txt
➜ command ls; (ls; ps)
command.txt
command.txt
PID TTY TIME CMD
17928 pts/0 00:00:02 zsh
25249 pts/0 00:00:00 ps
{command_1; command_2; command_3;} 执行大括号内一组命令
1
2
3
4
5
6
7
8
9
10
11
12
13
➜  command ls
command.txt
➜ command ls; {ls; ps}
command.txt
command.txt
PID TTY TIME CMD
17928 pts/0 00:00:02 zsh
25283 pts/0 00:00:00 ps
➜ command ls; {ls; ps;} | grep zsh
command.txt
17928 pts/0 00:00:02 zsh
➜ command {ls; ps;} | grep zsh
17928 pts/0 00:00:02 zsh
  • 这里(){}作用相近,但是又有区别。
    • 区别:
      • () 括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用
      • {} 在当前shell顺序执行命令,括号中的变量可以被脚本余下的部分使用
    • 在Shell交互式命令行中区别不大,可以忽略;在bash脚本中区别较大。
Donate comment here