Learning Bash¶
学习Bash,记录一些新学到的知识和tips。
Tips 1 &&和||¶
&&和||在条件判断时分别表示“逻辑与”和“逻辑或”,等同于在c中的功能。
另外,它们还可以直接用于命令后面,如:
command1 && command2 ||command3
上面的意思为:如果命令command1正常完成(返回0),则执行command2 如果command2执行时发生错误(返回非0),则执行command3。
如果commandn执行多条语句,可以写为command1; command2; ......,如果代码为下面的形式:
command1; command2 && command3; command4 || command5; command6
如果期待command2正常完成后执行command3和command4,出错时执行命令command5和command6。那就错了。上面的写法中,命令 command1, command2, command4, command6一定会被执行, command3,command5则依情况而定。如果期待如前所述,则必须将 command3; command4和 command5; command6用”`“括起来,如:
command1; command2 && `command3; command4` || `command5; command6`
Tips 2 关于删除文件时使用引号的疑问¶
假定目录结构如下:
目标是将目录abc清空。看看下面两个命令,你认为它们的效果是一样么?
rm -rf "abc/*"
rm -rf abc/*
动手试试上面两个命令,看看结果如何?第一个命令rm -rf "abc/\*"不能删除目录abc下的内容,而第二个命令可以。原因是什么?
Tips 3 防御型代码¶
今天看《Shell脚本学习指南》p307页时,发现一段代码:
grep POSTX_OPEN_MAX /dev/null $(find /usr/include -type f | sort)
就觉得奇怪,为什么要加一个/dev/null在grep后面。
因为如果$(find /usr/include -type f | sort)返回为空,grep命令就会一直等待终端输入,导致程序“卡死”。 添加一个/dev/null的作用就是防止find返回为空是程序卡死发生。
Tips 4 终端打印彩色文字¶
使用Shell在终端打印彩色文字:
echo -e "\e[32mHello World!\e[0m"
Python的print语句也可以利用相似的语法在终端打开彩色文字:
print("\x1B[32mHello World\x1B[0m")
# Python彩色文字
green = lambda string: '\x1B[32m%s\x1B[0m' % string
yellow = lambda string: '\x1B[31m\x1B[1m%s\x1B[0m' % string
red = lambda string: '\x1B[33m\x1B[1m%s\x1B[0m' % string
warning = lambda msg: '[%s]: %s' % (yellow('警告'), msg)
error = lambda msg: '[%s]: %s' % (yellow('错误'), msg)
Note
Below are the color init strings for the basic file types. A color init string consists of one or more of the following numeric codes:
- Attribute codes:
- 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
- Text color codes:
- 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
- Background color codes:
- 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
Tips 5 求N天前的日期字符串¶
个人觉得这个问题要完全正确是要花一点力气的,首先必须考虑以下情况:
- 每个月天数不一样,有28, 30, 31
- 存在闫年情况,二月份有29天
所以用Shell内置的功能偷了一下懒[1]:
#!/bin/bash
# Author: Liu Hui
#
# Date: Thu Jul 4 23:42:53 CST 2013
SECOND_TODAY=`date +%s`
SECOND_PER_DAY=86400
INTERVAL=7
SEQ=`seq $INTERVAL`
#set -x
for i in $SEQ
do
DATE=`echo "$SECOND_TODAY - $SECOND_PER_DAY * ${i}" | bc`
echo `date --date="@$DATE" +%Y%m%d`
done
#set +x
- 利用date命令自身功能更加简单方便:
date -d '-2 day' '+%Y%m%d'
# output: 20140118
参考资料¶
[1] | date命令用法详解 |