Pi & Kiss

Linux 的世界里, 最让人欲罢不能的就是里面的脚本的强大功能。让Windows 下的 .bat 批处理脚本实在是小巫见大巫。

然而在我们日常解决系统问题里,我们会经常用到 lsof 和 curl 这两个命令。今天要介绍的是 lsof -Pi 和 curl -kIsS ,还有一个 perl -p -i -e 很多人可能都已经听说过。

lsof 就是 list open file,查看内存中打开的文件,对于我们检查进程是否正常,特别是网络的端口占用,Unix Socket 的使用,共享库的使用等都能让我们一目了然。 lsof -i 就是用来检查打开的 Internet 侦听地址的进程的。

例如 lsof -i6 就是列出又有 IPv6 上侦听的进程,如果要检查 udp 53 端口是否打开,我们可以运行 lsof -i udp:53 ,然而这个 -i 命令的输出里,端口都不是数字,而是服务名称,这些名称其实是定义在 /etc/services 文件里的。那么如何显示端口号的数字呢? 我们只要 lsof -Pi 就可以了!

讲完 Pi , 我们讲 Kiss,当然, 提到 Kiss 你也不用想入非非。码农也好,网工也罢,curl 是个常用的 http(s) API 调用工具,当然也是文件下载的利器,如果我们仅仅只是要检查 http 头怎么办? 例如,对于饱受 QOS 困扰的国际求学的需求,我们经常需要检查 google 网站是否可以正常访问,这个时候我们只需要检查 http 是否能正常返回即可。 我们就可以用 proxychains4 curl -kIsS https://www.google.com/ 来检查我们设置在 proxychains 里的代理服务器是否能正常使用,来验证我们的国际求学之路没有被阻断。

最后提一下 perl 的 pie 替换功能。如果我们要替换一个文件里的文字,直接用 sed 是不能修改被修改文件本身的,但是 perl 的 pie 提供了这个功能。 例如我们要把文件里的“女生”修改为“美女”的话,用 perl -p -i -e ‘s/女生/美女/g’ test.txt 即可。

希望这种方式传播 Linux 知识能让你记忆更加深刻,喜欢我们的网站话,也可以拿起手机扫码屏幕右边关注我们的公众号,如果是手机搜索进入我们页面的话,屏幕底下也有公众号二维码。

How to write an Elegant Shell Script,怎样写一段优雅的 Shell 脚本

从一段简单的备份脚本说起, We will start from a simple backup script

这个脚本的目的是把一个 Web 目录用 tar cjf 打包,然后可以由不同的用户执行,不会有文件读写权限问题,每次打包前,要把之前的打包文件添加上日期备份好,如果打包失败,还要恢复。 The purpose of the demo script is to use “tar cjf” command to backup a web folder, different user can execute this script and will have no file permission issue. The original tarball file should be backup first to a new file name with date in the filename. In the case of failure, we will roll back the backup file.

我们会备份不同的 Web 目录,所以需要命令行传入参数,我们使用了 case 语句来判断,之所以没有用 if 是因为 if 语句会产生大量的 else 子句导致程序的可读性很差。 We will use this scrpt to backup different web folder, so the folder type is used as parameter to pass into the script. But we did not use if statement, because it will need lots “else” which will cause the script less readable. We use “case” statement to parse the “APP” name in this script.

为了记录是谁做的备份,我们需要写日志文件,而为了记录日志文件,我们写一个简单的 logger 函数,以参数传入的方式,把 logger 之后的参数 echo 显示,并添加到日志文件。 To record who and when, the user run the script, we write a function “logger”, which will need one “MSG” parameter, to echo and to append to the log file.

为了优雅的记录所有的日志,我们在日志的 MSG 前都添加了日志的 level, [debug], [info], [error], [warning] 等,我们之后如果需要分析日志,就可以简单的通过 grep 这些日志级别的关键字来查找。不同的用户可能在自己的环境会使用不同的语言设置 LC_ALL 变量,为了统一用英文,在脚本里,我们强行设置了 LC_ALL=”C”。 To record all the running log, we add log level verbosity in every MSG, e.g. [debug],[info],[error],[warning]. In case we need to find something in the log, we can just use these keywords to grep. Different user may have different language preference in their environment, to force the log file use all in English, we add LC_ALL=”C”.

为了记录所有可能的错误,我们在一些关键的执行命令后都添加了 “2>> $LOG” 这样的语句,这是为了记录可能的错误都写入到日志里。 To capture any ciritical error message, we add “2 >>$LOG” in every critial running command, so all the error log will be append to LOG file as well.

考虑到可能多人执行脚本,生成的文件权限会存在问题,我们用 umask 强制 owner 和 group 可写,同时把成功备份后的文件,强制设置为一个 同一个组 的组名。 Considered on the different user may execute the srcript, we have to make the file owner and group writeable(umask 002), and in the final step, in the success of the backup, we will change the target file’s group to a particular one, not the primary group of the executor.

好了,就说这么多吧,上全文
OK, That’s it, let just view the whole script.