bash: 日常开发使用
1. bash 是什么?
bash 是 linux 的默认登录 shell,它是一个命令处理器,用户在终端窗口中输入命令,bash 解释执行。
2. 常用的 bash 命令
- tab 自动补全功能
mkdi # 输入tab,bash 回返回或填充 mkdi为前缀的命令
mkdict mkdir
- bash shell 脚本常用符号
$*{environment}* # 该环境变量值
$? # 上个命令的退出状态,或函数的返回值。
$n # 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$# # 传递给脚本或函数的参数个数
$$ # 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
- bash if 语句常用参数
# 字符串判断
[ -z STRING ] 如果STRING的长度为零则返回为真,即空是真
[ -n STRING ] 如果STRING的长度非零则返回为真,即非空是真
[ STRING1 ] 如果字符串不为空则返回为真,与-n 类似
[ STRING1 == STRING2 ] 如果两个字符串相同则返回为真
[ STRING1 != STRING2 ] 如果字符串不相同则返回为真
[ STRING1 < STRING2 ] 如果 “STRING1”字典排序在“STRING2”前面则返回为真。
[ STRING1 > STRING2 ] 如果 “STRING1”字典排序在“STRING2”后面则返回为真。
# 数值判断
[ INT1 -eq INT2 ] INT1和INT2两数相等返回为真 ,=
[ INT1 -ne INT2 ] INT1和INT2两数不等返回为真 ,<>
[ INT1 -gt INT2 ] INT1大于INT2返回为真 ,>
[ INT1 -ge INT2 ] INT1大于等于INT2返回为真,>=
[ INT1 -lt INT2 ] INT1小于INT2返回为真 ,<
[ INT1 -le INT2 ] INT1小于等于INT2返回为真,<=
# 文件目录判断
[ -a FILE ] 如果 FILE 存在则为真。
[ -d FILE ] 如果 FILE 存在且是一个目录则返回为真。
[ -e FILE ] 如果 指定的文件或目录存在时返回为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则返回为真。
[ -r FILE ] 如果 FILE 存在且是可读的则返回为真。
[ -w FILE ] 如果 FILE 存在且是可写的则返回为真。(一个目录为了它的内容被访问必然是可执行的)
[ -x FILE ] 如果 FILE 存在且是可执行的则返回为真。
3. 利用 bash 完成常用的自动化工作
当您重复的输入命令时,就该考虑写个 shell 脚本了,当然 python 脚本运行,只不过还得配下 python 环境。
3.1 命令行启动、关闭应用(java应用)
- 启动一个 java 程序
#!/bin/bash
# Java ENV(若已添加到path中,该步骤可选)
export JAVA_HOME=/usr/java/jdk1.8.0_111
export JRE_HOME=${JAVA_HOME}/jre
# Apps Info
# 应用存放地址
APP_HOME=/xxx/
# 应用名称
APP_NAME=xxx.jar
# Shell Info
# 检查程序是否在运行
is_exist(){
# 获取PID
PID=$(ps -ef |grep “${JRE_HOME}/bin/java -jar ${APP_HOME}/${APP_NAME}” |grep -v grep |awk '{print $2}')
# -z "${pid}"判断pid是否存在,如果不存在返回1,存在返回0
if [ -z "${PID}" ]; then
# 如果进程不存在返回1
return 1
else
# 进程存在返回0
return 0
fi
}
# 启动程序
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is already running, PID=${PID}"
else
${JRE_HOME}/bin/java -jar ${APP_HOME}/${APP_NAME}
fi
- 关闭应用程序
#!/bin/bash
# Java ENV(若已添加到path中,该步骤可选)
export JAVA_HOME=/usr/java/jdk1.8.0_111
export JRE_HOME=${JAVA_HOME}/jre
# Apps Info
# 应用存放地址
APP_HOME=/xxx/
# 应用名称
APP_NAME=xxx.jar
# Shell Info
# 检查程序是否在运行
is_exist(){
# 获取PID
PID=$(ps -ef |grep “${JRE_HOME}/bin/java -jar ${APP_HOME}/${APP_NAME}” |grep -v grep |awk '{print $2}')
# -z "${pid}"判断pid是否存在,如果不存在返回1,存在返回0
if [ -z "${PID}" ]; then
# 如果进程不存在返回1
return 1
else
# 进程存在返回0
return 0
fi
}
# 关闭程序
is_exist
if [ $? -eq "0" ]; then
kill -9 ${PID}
echo "${APP_NAME} process stop, PID=${PID}"
else
echo "There is not the process of ${APP_NAME}"
fi
3.2 curl/wget 下载
How to download a Google Drive url via curl or wget
#!/bin/bash
fileid="### file id ###"
filename="MyFile.csv"
curl -c ./cookie -s -L "https://drive.google.com/uc?export=download&id=${fileid}" > /dev/null
curl -Lb ./cookie "https://drive.google.com/uc?export=download&confirm=`awk '/download/ {print $NF}' ./cookie`&id=${fileid}" -o ${filename}
3.3 连接数据库等应用
可以写个脚本执行,避免每次输命令,变量也可以参数方式给出
IP=xxx
PORT=xxx
USER=xxx
DATABSE=xxx
PASSWORD=xxx
mysql -h $IP -P $PORT -u $USER -D $DATABSE -p$PASSWORD
3.4 检测各项服务是否启动
echo "n service should be running."
services=(xxx xxx ... xxx)
for srv in ${services[@]}
do
pid=`ps -ef |grep $srv | grep -v auto | grep -v "\bgrep" | awk '{print $2}'`
if [ -n "$pid" ];then
echo "Service already runinng: $srv with pid $pid"
else
echo "Service not runinng: $srv "
fi
done
count=`ps -ef | grep -E "xxx|xxx|...|xxx" | grep -v auto | grep -v "\bgrep" | wc -l`
echo "Result: $count"
3.5 启动各项服务(go服务)
# Start shell
SERVICES_HOME=xxx
SERVICES_LOG=xxx
if [ "$#" -eq 0 ]; then
services=(xxx xxx ... xxx)
else
services=("$@")
fi
for srv in ${services[@]}
do
pid=`ps -ef |grep $srv | grep -v auto | grep -v "\bgrep" | awk '{print $2}'`
if [ -n "$pid" ];then
kill -9 "$pid"
echo "Stopping service: $srv with pid $pid"
fi
echo "Starting service: $srv"
cd $SERVICES_HOME/$srv
go build
# nohup & 放到后台运行
# 2>&1 将标准错误输出重定向到标准输出
nohup ./$srv & 2>&1 > $SERVICES_LOG$srv.log
echo "Start service: $srv done."
echo ""
done