目录

Linux输入输出

万物皆文件 – Linus Torvalds

重定向

标准输入流stdin的文件描述符是0,标准输出流stdout的文件描述符是1,标准错误流的文件描述符是2

标准输入流一般是键盘在终端的输入,标准输出流和错误输出流一般显示在终端屏幕上

我们可以将输入输出流重定向到其他文件

输出有>表示覆盖和>>表示追加,输入有<

注意像2>这种符号之间不能有空格

2>&1

2>&1表示把错误输出2,重定向>&到标准输出1所在的文件描述符(默认是终端屏幕)

command > file 2>&1表示command的标准输出先重定向到file,然后错误输出重定向到标准输出(现在是file),所以最后标准输出和错误输出都被重定向到file

command 2>&1 > file表示command的错误输出重定向到标准输出(现在是终端)(相当于啥事没发生),然后标准输出重定向到file,最后只有标准输出重定向到file,错误输出还是在终端输出

同理可以有1>&2等组合

各种命令

命令 作用
command > file 将command的标准输出重定向到file
command » file 将command的标准输出重定向到file
command 2> file 只将command的标准错误输出重定向到file
command 2» file 只将command的标准错误输出重定向到file
command 2>&1 将command的错误输出重定向到标准输出
command > file 2>&1 将command的标准输出和错误输出重定向到file,此时2>&1只能写在最后
command » file 2>&1 将command的标准输出和错误输出重定向到file,此时2>&1只能写在最后
command &> file command > file 2>&1的简写,注意简写&>只能放在file前,不能放在后面
command >& file 同command &> file
command &» file command » file 2>&1的简写,注意&»不能写成»&
command 2>&1 > file 将command的标准输出重定向到file
command 2>&1 » file 将command的标准输出重定向到file
command < input 将command的标准输入重定向到input
command « input 一直从键盘输入,直到遇到字符input,here-document方式
command «< input input为单行字符串,here- string方式,其中input用单引号和双引号效果不一样,详见参考
command < file1 > file2 将command的标准输入重定向到file1,标准输出重定向到file2

例子

command > file

1
2
3
4
5
dyh@0v0:~$ cat a
123
dyh@0v0:~$ echo 'hello' > a
dyh@0v0:~$ cat a
hello

command >> file

1
2
3
4
5
6
dyh@0v0:~$ cat a
hello
dyh@0v0:~$ echo 'world' >> a
dyh@0v0:~$ cat a
hello
world

command 2> file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
dyh@0v0:~$ cd 123
-bash: cd: 123: No such file or directory
dyh@0v0:~$ cat a
hehe
dyh@0v0:~$ cd 123 2> a
dyh@0v0:~$ cat a
-bash: cd: 123: No such file or directory
dyh@0v0:~$ cd 123 > a
-bash: cd: 123: No such file or directory
dyh@0v0:~$ cat a
dyh@0v0:~$ 

command 2>> file

1
2
3
4
5
6
dyh@0v0:~$ cat a
-bash: cd: 123: No such file or directory
dyh@0v0:~$ cd 124 2>> a
dyh@0v0:~$ cat a
-bash: cd: 123: No such file or directory
-bash: cd: 124: No such file or directory

command > file 2>&1

1
2
3
4
5
6
dyh@0v0:~$ cat a
qqq
dyh@0v0:~$ ls a b > a 2>&1
dyh@0v0:~$ cat a
ls: cannot access 'b': No such file or directory
a

command >> file 2>&1

1
2
3
4
5
6
7
8
9
dyh@0v0:~$ cat a
ls: cannot access 'b': No such file or directory
a
dyh@0v0:~$ ls a b >> a 2>&1
dyh@0v0:~$ cat a
ls: cannot access 'b': No such file or directory
a
ls: cannot access 'b': No such file or directory
a

command &> file

1
2
3
4
5
6
7
8
9
dyh@0v0:~$ cat a
ls: cannot access 'b': No such file or directory
a
ls: cannot access 'b': No such file or directory
a
dyh@0v0:~$ ls a b &> a
dyh@0v0:~$ cat a
ls: cannot access 'b': No such file or directory
a

command >& file

1
2
3
4
5
6
dyh@0v0:~$ cat a
111
dyh@0v0:~$ ls a b >& a
dyh@0v0:~$ cat a
ls: cannot access 'b': No such file or directory
a

command &>> file

1
2
3
4
5
6
7
8
9
dyh@0v0:~$ cat a
ls: cannot access 'b': No such file or directory
a
dyh@0v0:~$ ls a b &>> a
dyh@0v0:~$ cat a
ls: cannot access 'b': No such file or directory
a
ls: cannot access 'b': No such file or directory
a

command 2>&1 > file

1
2
3
4
5
6
dyh@0v0:~$ cat a
qqq
dyh@0v0:~$ ls a b 2>&1 > a
ls: cannot access 'b': No such file or directory
dyh@0v0:~$ cat a
a

command 2>&1 >> file

1
2
3
4
5
6
7
dyh@0v0:~$ cat a
a
dyh@0v0:~$ ls a b 2>&1 >> a
ls: cannot access 'b': No such file or directory
dyh@0v0:~$ cat a
a
a

command < input

1
2
3
4
5
6
7
8
dyh@0v0:~$ cat a
hello
world
hah
dyh@0v0:~$ wc -l a
3 a
dyh@0v0:~$ wc -l < a
3

command << input

1
2
3
4
5
6
7
8
dyh@0v0:~$ wc -l << a
> 123
> 456
> hello world
> yes
> no
> a
5

command <<< input

1
2
3
4
5
6
7
8
9
dyh@0v0:~$ tr a-z A-Z <<< aa
AA
dyh@0v0:~$ tr a-z A-Z <<< 'hello world'
HELLO WORLD
dyh@0v0:~$ tr a-z A-Z <<< "hello world"
HELLO WORLD
dyh@0v0:~$ tr a-z A-Z <<< aa bb
tr: extra operand ‘bb’
Try 'tr --help' for more information.

command < file1 > file2

1
2
3
4
5
6
7
8
9
dyh@0v0:~$ cat a
hello
world
hah
dyh@0v0:~$ tr a-z A-Z < a > r
dyh@0v0:~$ cat r
HELLO
WORLD
HAH
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
dyh@0v0:~$ cat a 
hello
world
hah
dyh@0v0:~$ cat > a << qq
> erfafsa
> fafssvadrfgh
> fvdsf
> qq
dyh@0v0:~$ cat a
erfafsa
fafssvadrfgh
fvdsf

/dev/null

将输出流重定向到/dev/null就会消失,像掉进黑洞一样

管道

管道将标准输出流转化成标准输入流

1
2
3
4
5
6
7
dyh@0v0:~$ ps -ef | grep "ba"
root          31       2  0 Nov22 ?        00:00:00 [writeback]
root         610       1  0 Nov22 ?        00:00:03 /usr/sbin/irqbalance --foreground
root        1086       1  0 Nov22 ttyS0    00:00:00 /sbin/agetty -o -p -- \u --keep-baud 115200,57600,38400,9600 ttyS0 vt220
root       10451   10361  0 20:18 pts/0    00:00:00 -bash
dyh        10468   10467  0 20:18 pts/0    00:00:00 -bash
dyh        10560   10468  0 21:02 pts/0    00:00:00 grep ba

有时候只使用管道是不行的,要通过xargs把标准输入转化成一个或多个下一个命令的参数,一般使用空格分开,但是如果标准输入中就有空格,需要额外处理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
dyh@0v0:~$ ls -l
total 12
-rw-r--r-- 1 dyh dyh   29 Nov 24 20:39 a
-rw-r--r-- 1 dyh dyh   15 Nov 24 21:13 aa
drwxr-xr-x 2 dyh dyh 4096 Nov 24 21:22 dir_a
dyh@0v0:~$ find ~ -name '*a*'
/home/dyh/aa
/home/dyh/a
/home/dyh/dir_a
dyh@0v0:~$ ls -l /home/dyh/aa /home/dyh/a /home/dyh/dir_a
-rw-r--r-- 1 dyh dyh   29 Nov 24 20:39 /home/dyh/a
-rw-r--r-- 1 dyh dyh   15 Nov 24 21:13 /home/dyh/aa

/home/dyh/dir_a:
total 0
dyh@0v0:~$ find ~ -name '*a*' | ls -l
total 12
-rw-r--r-- 1 dyh dyh   29 Nov 24 20:39 a
-rw-r--r-- 1 dyh dyh   15 Nov 24 21:13 aa
drwxr-xr-x 2 dyh dyh 4096 Nov 24 21:22 dir_a
dyh@0v0:~$ find ~ -name '*a*' | xargs ls -l
-rw-r--r-- 1 dyh dyh   29 Nov 24 20:39 /home/dyh/a
-rw-r--r-- 1 dyh dyh   15 Nov 24 21:13 /home/dyh/aa

/home/dyh/dir_a:
total 0

对于find命令,可以使用-exec选项

1
2
3
4
dyh@0v0:~$ find ~ -name '*a*' -exec ls -l {} \;
-rw-r--r-- 1 dyh dyh 15 Nov 24 21:13 /home/dyh/aa
-rw-r--r-- 1 dyh dyh 29 Nov 24 20:39 /home/dyh/a
total 0

不过如果要查找文件,最好用whereislocate,这两个都比find快,不过find是最强大的查找工具

find <path> -name <name> -exec <command> {} \;find <path> -name <name> | xargs <command>有什么区别

Q:

find <path> -name <name> -exec <command> {} \;find <path> -name <name> | xargs <command>都是Linux中的find命令,用于查找文件并对其执行指定的命令。两者的区别在于:

A:

  • find <path> -name <name> -exec <command> {} \;会对每个查找到的文件都执行一次指定的命令,而find <path> -name <name> | xargs <command>则会将所有查找到的文件名作为参数传递给xargs命令,然后再一次性地执行指定的命令。
  • find <path> -name <name> -exec <command> {} \;可以保证命令的执行顺序,而find <path> -name <name> | xargs <command>则不能保证命令的执行顺序。

例如,下面的命令将在当前目录下查找所有.txt文件,并对每个文件执行ls -l命令:

1
find . -name "*.txt" -type f -exec ls -l {} \;

而下面的命令则使用了xargs命令来执行相同的操作:

1
find . -name "*.txt" -type f | xargs ls -l

这两个命令的效果是相同的,但是第二个命令可能会更快,因为它可以将多个文件名作为参数传递给ls命令,从而减少了命令的执行次数.

总的来说,如果需要对每个查找到的文件执行指定的命令,并且命令的执行顺序很重要,那么应该使用-exec选项。如果只是需要对所有查找到的文件执行指定的命令,并且命令的执行顺序不重要,那么可以考虑使用xargs命令.

以上答案来自于gpt-4

xargs 处理空格输入

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
dyh@0v0:~$ ls -l
total 12
-rw-r--r-- 1 dyh  dyh    29 Nov 24 21:59  a
-rw-r--r-- 1 root root    0 Nov 24 22:00 'a a'
-rw-r--r-- 1 dyh  dyh    15 Nov 24 21:13  aa
drwxr-xr-x 2 dyh  dyh  4096 Nov 24 21:22  dir_a
dyh@0v0:~$ ls
 a  'a a'   aa   dir_a
dyh@0v0:~$ find ./ -name '*a*'
./aa
./a a
./a
./dir_a
dyh@0v0:~$ ls -l ./aa ./a\ a ./a ./dir_a
-rw-r--r-- 1 dyh  dyh    29 Nov 24 21:59  ./a
-rw-r--r-- 1 root root    0 Nov 24 22:00 './a a'
-rw-r--r-- 1 dyh  dyh    15 Nov 24 21:13  ./aa

./dir_a:
total 0
dyh@0v0:~$ find ./ -name '*a*' | ls -l
total 12
-rw-r--r-- 1 dyh  dyh    29 Nov 24 21:59  a
-rw-r--r-- 1 root root    0 Nov 24 22:00 'a a'
-rw-r--r-- 1 dyh  dyh    15 Nov 24 21:13  aa
drwxr-xr-x 2 dyh  dyh  4096 Nov 24 21:22  dir_a
dyh@0v0:~$ find ./ -name '*a*' | xargs ls -l
-rw-r--r-- 1 dyh dyh   29 Nov 24 21:59 ./a
-rw-r--r-- 1 dyh dyh   29 Nov 24 21:59 ./a
-rw-r--r-- 1 dyh dyh   29 Nov 24 21:59 a
-rw-r--r-- 1 dyh dyh   15 Nov 24 21:13 ./aa

./dir_a:
total 0
dyh@0v0:~$ find ./ -name '*a*' -print0 | xargs -0 ls -l
-rw-r--r-- 1 dyh  dyh    29 Nov 24 21:59  ./a
-rw-r--r-- 1 root root    0 Nov 24 22:00 './a a'
-rw-r--r-- 1 dyh  dyh    15 Nov 24 21:13  ./aa

./dir_a:
total 0

-print0-0意思是不用空格分割了,用null分割

参考

https://www.runoob.com/linux/linux-shell-io-redirections.html

https://www.redhat.com/sysadmin/linux-shell-redirection-pipelining

https://blog.csdn.net/succing/article/details/127355545

https://blog.csdn.net/weixin_43025343/article/details/132537234

https://luzejia.blog.csdn.net/article/details/112059493?spm=1001.2014.3001.5502

https://blog.csdn.net/oqqHuTu12345678/article/details/129282059

https://www.runoob.com/linux/linux-comm-xargs.html