shell 脚本简单概括和实践

阅读原文java

if 条件 OPTION

OPTION 解释
[-a file] 若是file存在则为真 ,也能够表示为 and: 条件与
if [ -z "condition1" -a -z "condition2" ]
[-b file] 若是file存在且是一个特殊文件则为真
[-c file] 若是file存在且是一个特殊文件则为真
[-d file] 若是 file 文件存在且是一个目录则为真,d前的!是逻辑非 
#表示目录不存在,则执行后面的 then 操做 
if [ ! -d lcd_path/par_date ]
[-e file] 若是 file文件存在则为真
[-f file] 若是 file 存在且是一个普通文件则为真
[-g file] 若是 file 存在且已经设置了SGID则为真(SUID 是 Set User ID, SGID 是 Set Group ID的意思)
[-h file] 若是 file 存在且是一个符号链接则为真
[-k file] 若是 file 存在且已经设置粘制位则为真
[-p file] 若是file存在且是一个名字管道(F若是O)则为真。管道是linux里面进程间通讯的一种方式,
其余的还有像信号(signal)、信号量、消息队列、共享内存、套接字(socket)等
[-r file] 若是file存在且是可读的则为真
[-s file] 若是file存在且大小不为0则为真
[-t FD] 若是文件描述符FD打开且指向一个终端则为真
[-u file] 若是file存在且设置了SUID(set userID)则为真
[-w file 若是file存在且是可写的则为真
[-x file] 若是file存在且是可执行的则为真
[-O file] 若是file存在且属有效用户ID则为真
[-G file] 若是file存在且属有效用户组则为真
[-L file] 若是file存在且是一个符号链接则为真
[-N file] 若是file存在and has been mod若是ied since it was last read则为真
[-S file] 若是file存在且是一个套接字则为真
[-o optionname] 若是shell选项“optionname”开启则为真
[-z string] “string”的长度为零则为真
[-n string] or [string] “string”的长度为非零non-zero则为真

if 基本判断

  • [file1 –nt file2] 若是file1 has been changed more recently than file2或者file1 exists and file2 does not则为真
  • [file1 –ot file2] 若是file1比file2要老,或者file2存在且file1不存在则为真
  • [file1 –ef file2] 若是file1和file2指向相同的设备和节点号则为真
  • [sting1==string2] 若是2个字符串相同。“=”may be used instead of “==”for strict posix compliance则为真
  • [string1!=string2] 若是字符串不相等则为真
  • [string1<string2] 若是“string1”sorts before“string2”lexicographically in the current locale则为真
  • [arg1 OP arg2]  “OP”is one of –eq,-ne,-lt,-le,-gt or –ge

截取字符串

  • # 号截取,删除左边字符,保留右边字符。 (非贪婪匹配)
var=http://www.glmapper.com
# # 号是运算符,*/ 表示从左边开始删除第一个 / 号及左边的全部字符,即删除 http://
echo ${var#*//}
#结果 www.glmapper.com
复制代码
  • ## 号截取,删除左边字符,保留右边字符。(贪婪匹配)****
var=http://www.glmapper.com
# ##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的全部字符
echo ${var##*//}

# 结果 www.glmapper.com
复制代码
  • %号截取,删除右边字符,保留左边字符 (非贪婪匹配)
var=http://www.glmapper.com
# %/* 表示从右边开始,删除第一个 / 号及右边的字符
echo ${var%/*}
# 结果是:http:/
复制代码
  • %% 号截取,删除右边字符,保留左边字符  (贪婪匹配)
var=http://www.glmapper.com
# %%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符
echo ${var%%/*}
# 结果 :http: 
复制代码
  • 从左边第几个字符开始,及字符的个数
var=http://www.glmapper.com
# 其中的 0 表示左边第一个字符开始,5 表示字符的总个数
echo ${var:0:5}
# 结果 http:
复制代码
  • 从左边第几个字符开始,一直到结束
var=http://www.glmapper.com
# 其中的 7 表示左边第8个字符开始,一直到结束。
echo ${var:7}
# 结果 www.glmapper.com
复制代码
  • 从右边第几个字符开始,及字符的个数
var=http://www.glmapper.com
# 其中的 0-3 表示右边算起第3个字符开始,3 表示字符的个数
echo ${var:0-3:3}
# 结果 com
复制代码
  • 从右边第几个字符开始,一直到结束
var=http://www.glmapper.com
# 表示从右边第 3 个字符开始,一直到结束
echo ${var:0-3}
# 结果 com
复制代码

左边的第一个字符是用 0 表示,右边的第一个字符用 0-1 表示linux

basename

basename 命令简介

去除文件名的目录部分和后缀部分。basename 命令读取 String 参数,删除以 /(斜杠) 结尾的前缀以及任何指定的 Suffix 参数,并将剩余的基本文件名称写至标准输出。basename 和 dirname 命令一般用于 shell 脚本中的命令替换来指定和指定的输入文件名称有所差别的输出文件名称。
**
基本语法以下:shell

basename NAME [SUFFIX]
basename OPTION
复制代码

基本示例

basename /usr/bin/sort
# 返回 sort

basename /usr/bin/sort/glmapper.txt
# 返回 glmapper.txt
复制代码

建立基本文件名称的规则

  • 若是 String 参数是 //(双斜杠) 或若是 String 参数包含的都是斜杠字符,则将字符串更改成单个 /(斜杠)
basename //usr//bin//sort//glmapper.txt
# 返回 glmapper.txt

basename ////
# 返回 /
复制代码
  • 从指定字符串除去任何拖尾的 / 字符。
basename /usr/bin/sort/
# 返回 sort
复制代码
  • 若是在 String 参数中剩余任何 / 字符,则除去字符串的前缀直到(包含)最后一个 / 字符。
  • 若是指定 Suffix 参数,且它和字符串中的剩余的字符相同,则不修改此字符串
basename /usr/bin/sort/glmapper.txt glmapper.txt 
# 返回glmapper.txt 

basename /usr/bin/sort/glmapper.txt .txt 
# 返回 glmapper
复制代码

shell 查看当前目录下文件的个数

测试准备,test 目录下有 test一、test2 两个文件夹和一个 1.txt 文件。bash

-test
├── 1.txt
├── test1
│   └── test1_1.txt
└── test2
复制代码
  • 查看当前目录下文件的个数
test ls -l | grep "^-" | wc -l
   1 # 1.txt
复制代码
  • 查看当前目录下文件的个数,包括子目录里的
test ls -lR| grep "^-" | wc -l
   2 # 1.txt test1_1.txt
复制代码
  • 查看某目录下文件夹(目录)的个数,包括子目录里的
test ls -lR| grep "^d" | wc -l
	 2 # test1 test2
复制代码
  • 说明:
一、ls -l :长列表输出该目录下文件信息(注意这里的文件,不一样于通常的文件,多是目录、连接、设备文件等)
二、grep "^-" :这里将长列表输出信息过滤一部分,只保留通常文件,若是只保留目录就是 ^d
三、wc -l : 统计输出信息的行数,已通过滤得只剩通常文件了,统计结果就是通常文件信息的行数,
					又一行信息对应一个文件,也就是文件的个数
复制代码

利用简单的命令组合实现配置文件的获取

测试准备,在 1.txt 中 增长两个属性:app

name=glmapper
age=26
复制代码
cat /Users/guolei/logs/test/1.txt | sed 's|[[:blank:]]||g' | grep "^name=" | cut -d= -f2
# 返回 glmapper 

cat /Users/guolei/logs/test/1.txt | sed 's|[[:blank:]]||g' | grep "^age=" | cut -d= -f2
# 返回 26
复制代码

函数封装与返回

以上面的解析配置文件为例,将其封装成一个函数socket

function load_param()
{
    # 接受的第一个参数是文件地址
    local properties_file=$1
    # 接受的第二个参数是属性名
    local param=$2
    RESULT=`cat $properties_file | sed 's|[[:blank:]]||g' | grep "^$param=" | cut -d= -f2`
}
复制代码

调用函数而且获取返回值函数

load_param 1.txt name
PROP_VAL=$RESULT
echo $PROP_VAL
# 返回 glmapper
复制代码

shell 实现日志文件的归档处理

日志归档简单来讲就是,每次但愿启动,会将前一次程序运行产生的日志和本地运行产生的日志隔离开来,归档结果就是产生相似于以下的日志文件:测试

  • stdout.log.20170909
  • stdout.log.20170709
  • stdout

因此日志文件的归档在生产脚本中是必需要考虑的,不然就到致使每次产生的文件都会被写入同一份日志文件中。下面是实践过程当中概括的一个日志归档函数:ui

# archive log
function archive_log() {
    local FILE_STDOUT_LOG=$LOG_ROOT/stdout.log
    local FILE_STDERR_LOG=$LOG_ROOT/stderr.log
    if [ ! -e $LOG_ROOT ] ; then
        mkdir -p $LOG_ROOT
    fi
    NOW=`date +%Y%m%d.%H%M%S`
    # scroll SOFABoot STDOUT log
    if [ -e $FILE_STDOUT_LOG ] ; then
        mv $FILE_STDOUT_LOG $FILE_STDOUT_LOG.$NOW
    fi

    # scroll SOFABoot STDERR log
    if [ -e $FILE_STDERR_LOG ] ; then
        mv $FILE_STDERR_LOG $FILE_STDERR_LOG.$NOW
    fi

    FILE_STDOUT_LOG_GLOBAL=$FILE_STDOUT_LOG;
    FILE_STDERR_LOG_GLOBAL=$FILE_STDERR_LOG;
}
复制代码

一个简单的 SOFABoot 启动脚本

deploy.sh  简单的启动脚本:spa

LOG_ROOT= $1;
APP_PATH= $2;
# 检查 JAVA_HOME
if [ -z "$JAVA_HOME" ]; then
  echo "JAVA_HOME not set, exit"
  exit 1
fi
# 使用前面的那个日志归档函数
archive_log

# 启动 java 程序
java -jar $APP_PATH >> $FILE_STDOUT_LOG_GLOBAL 2>> $FILE_STDOUT_LOG_GLOBAL &
复制代码

运行:

sh deploy.sh ./logs app.jar 
复制代码

小结

本文记录平常中常遇到的 shell 命令,基础知识部分零碎的参考了网上一些同窗的博客,在此作了概括。也欢迎你们指正。若是你有比较骚气的操做,也欢迎评论席留言,我会验证后更新到文章中来。

相关文章
相关标签/搜索