管道与重定向、文件查找-Linux每日一练(7)
共 2448字,需浏览 5分钟
·
2020-09-19 14:14
拢共有 11 篇 Linux 知识点梳理的文章,这次是第 7 篇,梳理完以后 Linux 每日一练就结束更新了,但是还没有完结,后续如果有什么比较重要的 Linux 知识会单独抽出来再讲。
上次我们着重讲解了进程管理的知识,这一节提一下管道、重定向、文件查找。
重定向
在解答上次的重定向问题之前,简单提一下什么是重定向。
Unix 系统中,每个进程都有 STDIN
、 STDOUT
和 STDERR
这 3 种标准 I/O
。所以几乎所有语言都有相应的标准 I/O
函数,比如 printf
、 println
、 scanf
等命令,专门用来接收用户的输入,或者打印输出到屏幕、或者文件里。
在 SHELL
里面重定向相当的方便,只需要用 >
或 >>
符号就可以了。当然我们也可以直接通过命令把 3 种 I/O
区别开,分别输出。
题目一:>
和 >>
有什么区别?
>
是覆盖写入,原来的内容全部清空。
$ echo no > test.txt
$ echo ok > test.txt
$ cat test.txt
ok
>>
是追加写入,在原来内容末尾追加。
$ echo no >> test.txt
$ cat test.txt
ok
no
下面是他的定义,了解一下即可,不用记得。
标准输入文件(stdin):stdin 的文件描述符为 0,Unix 程序默认从 stdin 读取数据。 标准输出文件(stdout):stdout 的文件描述符为 1,Unix 程序默认向 stdout 输出数据。 标准错误文件(stderr):stderr 的文件描述符为 2,Unix 程序会向 stderr 流中写入错误信息。
好了,我们知道输出/错误输出信息分别用数字 1 和 2 代表,你肯定见过下面的写法
java -jar app.jar >log 2>&1 &
这里的, 2>&1
代表把错误输出2
合并到1
中,并重定向到名为log
的文件中去。符号 >&
是一个整体,不可分开,分开后就不是上述含义了。比如有些人可能会这么想:2
是标准错误输入,1
是标准输出,>
是重定向符号,那么"将标准错误输出重定向到标准输出"是不是就应该写成2>1
就行了?是这样吗?如果是尝试过,你就知道2>1
的写法其实是将标准错误输出重定向到名为1
的文件里去了
2>&1
符号必须放到 >log
后面,为什么呢?我们不妨把 1 和 2 都理解是一个指针, 然后来看上面的语句就是这样的:
本来 1----->屏幕 (1 指向屏幕) 执行>log 后, 1----->log (1 指向 log) 执行 2>&1 后, 2----->1 (2 指向 1,而 1 指向 log, 因此 2 也指向了 log)
题目二:重定向怎么把错误输出和正确输出分离开?
正确输出: 1>
1>>
等价于>
>>
错误输出: 2>
2>>
运维过程中几乎用不到,就不用记了,hhhh
题目三:怎么快速把一个非常大的文本文件清理掉?
用 rm
或者 echo > filename
都会占用很大的内存,而且速度很慢,建议使用下面的方法
cat /dev/null > filename
/dev/null
是一个特殊的设备文件, 在程序员行话,尤其是 Unix
行话中, /dev/null
被称为位桶(bit bucket)或者黑洞(black hole)。他会把一些写入丢弃,如果你读取它,它会提供无限的空字符(NULL, ASCII NUL, 0x00)。
你肯定也用到过,只不过不一定理解是什么含义,例如在定时任务脚本结尾加上 >/dev/null 2>&1
,让所有的输出流(包括错误的和正确的)都定向到空设备丢弃。
* * * * * /bin/mysqlbak.sh >/dev/null 2>&1
题目四:使用管道完成,组合 ps
、 grep
、 awk
、 xargs
、 kill
命令为一行命令,干掉名为 apache
的进程
ps -ef |grep apache | awk '{print $2}'| xargs kill -9
但是这个命令一般执行的时候还是有风险的,而且杀进程也比较粗暴,我们都想做温柔的人,建议发送信号给程序,在程序里处理信号做一些析构的工作(当然,我知道大家的程序基本上都懒得写这些)
也推荐用 systemctl
、 supervisor
、容器等守护进程托管你的程序,比较安全可靠。
拓展运维技巧,向文件中写入多行内容
下面这种形式很特别
命令 <....
EOF //结束
样例,输出是 3:
wc -l <a
b
c
EOF
如果你把 wc -l
命令换成 cat
就是打印输入的内容,然后再将它重定向追加到文件里即可完成向文件写入多行内容。
比如你想写入多个 hosts 隐射,你就可以用 EOF
的特性,自己测试下看看吧!
cat<> /etc/hosts
10.1.1.2 k8smaster
10.1.1.3 k8snode1
10.1.1.4 k8snode2
EOF
小结
>
重定向并清空,>>
重定向追加2>&1
合并正确和错误输出流,如果是打印到屏幕上的脚本,必须要加cat /dev/null > filename
快速清理文件内容xxx.sh >/dev/null 2>&1
丢球所有输出流(包括错误的和正确的)。ps -ef |grep processname | awk '{print $2}'| xargs kill -9
杀进程
参考:
https://blog.csdn.net/zhaominpro/article/details/82630528 https://www.cnblogs.com/lishihai/p/7986565.html
下次主题,软件包管理、计划任务
其实软件包管理我已经在三分钟手操 yum 源和打 rpm 包是如此的迅速(go 语言之美)两篇文章中有所提及,大家可以下来了解下
题目一:如何使用 yum
安装 git
的 1.8.3.1-20.el7
版本包?
题目二:如何安装和卸载 rpm
包?
题目三:如何使用 crontab
创建一个定时任务,每天晚上 3 点 10 分执行一次,并忽略输出?