/ code-snippet  

Shell Code Snippet

查找大文件

du -s ./*|sort -nr|head -3

一般说来不会出现删除文件后空间不释放的情况,但是也存在例外,比如文件被进程锁定,或者有进程一直在向这个文件写数据等等,要理解这个问题,就需要知道 Linux 下文件的存储机制和存储结构。

一个文件在文件系统中的存放分为两个部分:数据部分和指针部分,指针位于文件系统的 meta-data 中,数据被删除后,这个指针就从 meta-data 中清除了,而数据部分存储在磁盘中,数据对应的指针从 meta-data 中清除后,文件数据部分占用的空间就可以被覆盖并写入新的内容,之所以出现删除 access_log 文件后,空间还没释放,就是因为 httpd 进程还在一直向这个文件写入内容,导致虽然删除了 access_log 文件,但文件对应的指针部分由于进程锁定,并未从 meta-data 中清除,而由于指针并未被删除,那么系统内核就认为文件并未被删除,因此通过 df 命令查询空间并未释放也就不足为奇了。

# 获取一个已经被删除但仍然被应用程序占用的文件列表
lsof | grep delete

通过这种方法,磁盘空间不但可以马上释放,也可保障进程继续向文件写入日志,这种方法经常用于在线清理 Apache、Tomcat、Nginx 等 Web 服务产生的日志文件:

echo " " >/tmp/acess.log

grep 遍历文件夹查找文本内容

有时候我们需要在某一个包含很多子目录的目录中搜索查找包含某个文本内容的文本,我们可以在 grep 中加上 -r 选项让 grep 命令迭代进入子目录查找。同时在命令最后加上代表文件通配符的*号,不然 grep 会一直等待输入。

grep -r "查找文本内容" *

set

#!/usr/bin/env bash

set -o errexit #等价 set -e。只要发生错误,就终止执行。认为非0就是错误。
set +o nounset # 等价 set +u。遇到不存在的变量不报错。默认如此。
set -o pipefail # 只要一个子命令失败,整个管道命令就失败,脚本就会终止执行。
set -o xtrace # 等价 set -x。在运行结果之前,先输出执行的那一行命令,调试复杂的脚本是很有用。
set -o errexit
set -o nounset
set -o pipefail
set -o xtrace

# 4合1
set -euxo pipefail
## 写法二
set -eux
set -o pipefail

# 或者执行命令时
bash -euxo pipefail script.sh

如果脚本里面有运行失败的命令(返回值非 0),Bash 默认会继续执行后面的命令。

实际开发中,如果某个命令失败,往往需要脚本停止执行,防止错误累积。这时,一般采用下面的写法:

command || exit 1

上面的写法表示只要 command 有非零返回值,脚本就会停止执行。

如果停止执行之前需要完成多个操作,就要采用下面三种写法:

# 写法一
command || { echo "command failed"; exit 1; }

# 写法二
if ! command; then echo "command failed"; exit 1; fi

# 写法三
command
if [ "$?" -ne 0 ]; then echo "command failed"; exit 1; fi

如果两个命令有继承关系,只有第一个命令成功了,才能继续执行第二个命令,那么就要采用下面的写法:

command1 && command2

CDPATH

# Unset CDPATH so that path interpolation can work correctly
unset CDPATH
export CDPATH=/etc
cd mail
/etc/mail

Ubuntu 命令行下设置时区

  • Ubuntu 16.04
sudo dpkg-reconfigure tzdata

按提示进行选择完成。

设置完成后发现在 crontab 仍然是按 UTC 执行的,应该是需要重启下系统或者:

/etc/init.d/rsyslog restart

Ubuntu 命令行下打开 PDF

一个文件夹中存放了大量的文件后,在窗口打开中被打开时是非常耗时的。当我们已经明确知道文件名时,可以直接在 Terminal 中使用命令,调用应用打开文件:

evince filename.pdf

References

– EOF –