“test-jb-setup”
shell脚本在运维中非常实用,但是也因为是脚本语言,书写调试等方面都会比较困难。以下记录学习过程中用到的内容。当然下面介绍的应该是基于bash的,曾经用过AIX下面的ksh,不太习惯。
1. 如何编写和运行脚本
应景,shell脚本以sh为扩展名,实际上这个没关系。只要有执行权限即可。
vi xxx.sh
chmod +x xxx.sh
./xxx.sh
2. 如何传递参数和获取参数
参数传递比较简单,命令行后面用空格分开就可以,如
./xxx.sh 参数1 参数2
脚本中如果要使用通过$符号加序号即可获取,如
param1=$1
param2=$2
……
3. 变量使用
从上面我们看到变量其实可以简单的用 $ 显示,变量的定义比较简单,直接设置即可,引用的时候需要用$包裹,如
var1=test
echo $var1
echo ${var1}
从上面可以看出来,用 $ 或者 ${} 加变量名都可以,建议包裹一下,不容易混起来。
注意事项
- 变量声明的时候,= 前后不能加空格,也比较坑爹的
如果想把一个命令的执行结果放到变量里面,可以用$()包裹,如
var1=$(ps -ef|grep tomcat)
echo ${var1}
还有一个比较特别的用法,获取当前脚本里面指定前缀或者后缀的变量,形成一个数组,如
var1=“var1”
var2=“var2”
vars=${!var*}
echo ${vars} # var1 var2
vars2=${!1@} # var1
4. 字符串
-
拼接字符串
在脚本里面字符串拼接倒是比较简单,直接2个变量放一起就行了
var1=$(ps -ef|grep tomcat)
echo ${var1}”hello”
- 字符串截取
- 从指定位置开始截取,后面的长度是可选项
var1=“hello”
echo ${var1:1}
echo ${var1:1:3}
- 删除指定字符串
原始字符串var1: 123heolhhlo
替换字符串var2: o
${var1:1} ==\> 23heolhhlo
${var1:2:2} ==\> 3h
${var1\#*${var2}} ==\> lhhlo
${var1\#*h} ==\> eolhhlo
${var1#\#*$var2} ==\>
${var1#\#*h} ==\>
==============
${var1%*$var2} ==\> 123heolhhl
${var1%%*$var2} ==\>
${var1%%*h} ==\> 123heolhhlo
==============
${var1/h/i} ==\> 123ieolhhlo
${var1//h/i} ==\> 123ieoliilo
==============
${var1/%h/i} ==\> 123heolhhlo
${var1/${var2}/i} ==\> 123heilhhlo
==============
${var1//${var2}/i} ==\> 123heilhhli
${var1/%${var2}/i} ==\> 123heolhhli
可以用来处理获取文件名,扩展名,路径等等。总的来说,# 表示前缀,% 表示后缀
5. 数组
脚本写多,多半会碰到需要用到数组的地方,生成数组的方法比较多,用得比较多还是通过其他命令获取出来的。
arr=$(ls)
arr=(1 2 3 4 5)
- 长度获取
echo ${#arr[ @ ]()}
- 获取值
下标从0开始
echo ${arr[2]()}
echo ${arr[*]()}
- 赋值
arr[0]()=0
- 删除
unset arr
unset arr[1]()
6. 循环
主要介绍数组循环,
for vv in ${arr[@]()}
do
echo ${vv}
done
7. 函数
- 基本形式
function test(){
p1=$1
p2=$2
return 0
}
函数如果要有参数,不用在括号里面写,引用的时候,用 $加数字即可,当然也有可能没有,但是变量的作用域默认是全局的,也就是说这个函数里面定义了一个变量,出了函数还能用,如果是局部用,可以在变量前面加 local关键字
- 返回值
默认返回就是数字,所以无法返回字符串,一种做法就是通过全局变量来处理
8. 文件引用
如果代码很多,需要重复引用,可以整理到一个单独的文件,其他文件包含它即可。引用很简单,文件名前面一个 .即可。
. 文件名
注意这里的空格。文件名可以用相对路径也可以是绝对路径,各有利弊,但是需要注意,相对路径指运行命令的路径。
9. 注意事项
使用变量的时候,不要加空格
shell 文件包含
参考资料
http://www.runoob.com/linux/linux-shell-include-file.html
http://arganzheng.iteye.com/blog/1174470
http://www.cnblogs.com/chengmo/archive/2010/10/17/1853356.html
shell 返回字符串 http://tinyweb.blog.51cto.com/2462673/982616
http://www.coder4.com/archives/3853
shell如何判断参数是一个文件还是一个文件夹? if [ -d $1 ];then ehco “$1 是目录” elif [ -f $1 ];then echo “$1 是文件” fi
http://www.cnblogs.com/chengmo/archive/2010/10/02/1841355.html
这里的东西比较全面,特别是字符串相关的
function contains() { local n=$# local value=${!n} for ((i=1;i < $#;i++)) { if ”${!i}” == “${value}” ; then echo “y” return 0 fi } echo “n” return 1 }
pidc=$(pgrep -f tomcat) echo “>>>12.jstack<<<” >>${filename} echo “ pid: “${pidc}”, 对应线程情况:” >>${filename} ps -mp ${pidc} -o THREAD,tid,time |awk ‘{print $2 “ “$8}’ |sort|tail -n 6|head -n 4 >>${filename} tidcs=$(ps -mp ${pidc} -o THREAD,tid,time |awk ‘{print $2 “ “$8}’ |sort|tail -n 6|head -n 4|awk ‘{print $2}’)
for tidc in ${tidcs@} do echo “ tid:”${tidc}>>${filename} ttidc=$(printf “%x\n” ${tidc}) jstack ${pidc} |grep ${ttidc} -A 100 >>${filename} echo “ =====”>>${filename} done
echo “============”>>${filename}
su - <user> -c “bash -c ‘cd $DIR ;<service name>’”
shell的服务脚本里面加这个
==
在shell脚本中,无法对浮点数进行比较,如:
max=0.1
min=0.01
if ”$max” -gt “$min”
then
echo “YES”
else
echo “NO”
fi
这样的比较,运行后得到错误:
line 4: : 0.1: integer expression expected
因为bc和awk都支持浮点数,可以使用bc进行处理:
max=0.1
min=0.01
if echo "$max > $min" | bc
-eq 1
then
echo “YES”
else
echo “NO”
fi
也可以写成if $(echo “$max < $min”|bc) -eq 1
http://www.cnblogs.com/sunyubo/archive/2011/10/17/2282047.html 判断文件是否存在
几个坑,因为以前为了代码美观,= 号两头有空格,现在shell公然不支持,