管道与重定向、文件查找-Linux每日一练(7)

2020年9月18日 评论 107 views 2314字阅读7分42秒

拢共有11篇Linux知识点梳理的文章,这次是第7篇,梳理完以后Linux每日一练就结束更新了,但是还没有完结,后续如果有什么比较重要的Linux知识会单独抽出来再讲。

上次我们着重讲解了进程管理的知识,这一节提一下管道、重定向、文件查找。

重定向

在解答上次的重定向问题之前,简单提一下什么是重定向。

Unix系统中,每个进程都有 STDINSTDOUTSTDERR 这3种标准 I/O 。所以几乎所有语言都有相应的标准 I/O 函数,比如 printfprintlnscanf 等命令,专门用来接收用户的输入,或者打印输出到屏幕、或者文件里。

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

题目四:使用管道完成,组合 psgrepawkxargskill 命令为一行命令,干掉名为 apache 的进程

ps -ef |grep apache | awk '{print $2}'| xargs kill -9

但是这个命令一般执行的时候还是有风险的,而且杀进程也比较粗暴,我们都想做温柔的人,建议发送信号给程序,在程序里处理信号做一些析构的工作(当然,我知道大家的程序基本上都懒得写这些)

也推荐用 systemctlsupervisor 、容器等守护进程托管你的程序,比较安全可靠。

拓展运维技巧,向文件中写入多行内容

下面这种形式很特别

命令 <<EOF        //开始
....
EOF            //结束

样例,输出是3:

wc -l <<EOF
a
b
c
EOF

如果你把 wc -l 命令换成 cat 就是打印输入的内容,然后再将它重定向追加到文件里即可完成向文件写入多行内容。

比如你想写入多个hosts隐射,你就可以用 EOF 的特性,自己测试下看看吧!

cat<<EOF >> /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 安装 git1.8.3.1-20.el7 版本包?
题目二:如何安装和卸载 rpm 包?
题目三:如何使用 crontab 创建一个定时任务,每天晚上3点10分执行一次,并忽略输出?

weinxin
公众号
在号内与我交流,回复【资源】获取技术大礼包
Linux最后更新:2020-10-5
小熊