Linux的shell脚本语法
shell脚本
#!/bin/bash
# 文件要以上面开始,.sh结尾的文件不需要
# 赋权文件可执行权限
chmod +x <fileName>
# 获取java jar包启动的进程id
ps -ef | grep *.jar | grep -v grep | awk '{print $2}'
shell变量
变量命令规则:
- 只能包含字母、数字、下划线;
- 不能以数字开口,可以包含数字;
- 不能使用Shell的关键字作为变量名( if、then、else、fi、for、while)
- 使用大写字母表示常量;
- 变量赋值不能使用空格,例如:PID=“pid”;
使用变量
#!/bin/bash
PID="pid"
P1=`ps -ef | grep *.jar | grep -v grep | awk '{print $2}'` # 1.使用命令执行结果作为变量
P1=`ps -ef | grep *.jar | grep -v grep | awk "{print $2}"` # 1.使用命令执行结果作为变量
P2="`ps -ef | grep *.jar | grep -v grep | awk '{print $2}'`" # 1.使用命令执行结果作为变量
PID=$(ps -ef | grep *.jar | grep -v grep | awk '{print $2}') # 2.
# 使用变量
echo $PID
echo "P1=$PID"
echo 'P2=$PID'
echo 'P3=''$PID' # 特殊字符'要成对
echo ${PID}
# 设置只读
only_read="Java"
readonly only_read
only_read="python" #会有提示
# 删除变量(不能删除只读变量)
unset only_read
echo ${only_read}
注意:
name = "zhangsan"
# 这里${nmae}或$name会把值当成变量来获取
echo "name: ${name}"
变量类型
字符串
在 Shell中,变量通常被视为字符串。
可以使用’'或""来定义变量
单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字符串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
双引号的优点:
双引号里可以有变量;
双引号里可以出现转义字符。
# 字符串变量
s1="Hello World"
s2='Hello World'
echo 'P3=''$PID' # 特殊字符'要成对
获取字符串长度
# 获取字符串长度
${#变量名}
${#变量名[0]}
name = "zs"
echo ${#name}
截取字符串
# 索引是从0开始,string字符串第二个字符开始,截取4个字符
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
查找子字符串
# 查找字符 i 或 o 的位置(哪个字母先出现就计算哪个,从1开始计算)
string="runoob is a great site"
echo `expr index "$string" io` # 输出 4
整数变量
declare -i age=42
数组变量
array=(1 2 3 4 5)
declare -A associative_array
associative_array["name"]="John"
associative_array["age"]=30
# 单独定义数组的各个分量
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
读取数组
${数组名[下标]}
${array_name[0]}
# 使用@获取数组所有元素
echo ${array_name[@]}
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
length=${#array_name[n]}
环境变量
由操作系统或用户设置的特殊变量,用于配置 Shell 的行为和影响其执行环境。
echo $变量名
echo $JAVA_HOME
特殊变量
有一些特殊变量在 Shell 中具有特殊含义,例如 $0 表示脚本的名称,$1, $2, 等表示脚本的参数。
流程语句
if流程
if
#!/bin/sh
if condition
then
command1
command2
...
commandN
fi
#!/bin/sh
#!/bin/bash
cygwin=false
darwin=false
os400=false
case "CYGWINCYGWIN" in
CYGWIN*) cygwin=true;;
Darwin*) darwin=true;;
OS400*) os400=true;;
*)
echo `uname`
;;
esac
if $cygwin; then
echo "cygwin true";
fi
# 结果cygwin true
if-else
if condition
then
command1
command2
...
commandN
else
command
fi
if else-if else
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
case
类似其他编程语言的switch语句。
# 语法
# expression 待匹配的值(变量、命令的输出)
# pattern1,pattern2... 匹配值,可以是字符串、正则表达式
# statements1,statements2... 匹配成功待执行的命令
# *表示默认匹配模式
case expression in
pattern1)
statements1
;;
pattern2)
statements2
;;
...
patternN)
statementsN
;;
*)
default_statements
;;
esac
#!/bin/bash
for循环
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
while循环
while condition
do
command
done
#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
# :表示启用getopts的错误处理模式,如果遇到未知选项,opt的值会变成?,而不是输出错误信息
# m:表示该选项需要一个参数,-m选项之后必须跟一个值
# $OPTARG表示后面跟的值
while getopts ":m:f:s:c:p:" opt
do
case $opt in
m)
echo $OPTARG;;
f)
echo $OPTARG;;
s)
echo $OPTARG;;
c)
echo $OPTARG;;
p)
echo $OPTARG;;
?)
echo "Unknown parameter"
exit 1;;
esac
done
运算符
算数运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
注意:
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2;
完整表达式需要``包裹;
``执行反引号中的命令并将输出结果替换为命令输出。
val=`expr 2 + 2`
echo "两数之和为 : $val"
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
布尔运算符
逻辑运算符
字符串运算符
文件测试运算符
函数
参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return 后跟数值 n(0-255)。
函数返回值在调用该函数后通过 $? 来获得。
注意:
所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可;
调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个;
$10 不能获取第十个参数,获取第十个参数需要
10
。当
n
>
=
10
时,需要使用
{10}。当n>=10时,需要使用
10。当n>=10时,需要使用{n}来获取参数。
# 定义函数语法
[ function ] funname [()]
{
action;
[return int;]
}
shell命令
shell_1
#!/bin/sh
SERVICE_NAME="lgsa-portRelease-mgr"
ENVFILE="../env"
PIDFILE="pid"
checkRunning(){
if [ -f "$PIDFILE" ]; then
if [ -z "`cat $PIDFILE`" ];then
echo "ERROR: Pidfile '$PIDFILE' exists but contains no pid"
return 2
fi
PID="`cat ${PIDFILE}`"
RET="`ps -p "${PID}"|grep java`"
if [ -n "$RET" ];then
echo "${RET}"
return 1;
else
return 0;
fi
else
return 0;
fi
}
status(){
if ( checkRunning );then
PID="`cat $PIDFILE`"
echo "'$SERVICE_NAME' is running (pid '$PID')"
exit 0
fi
echo "'$SERVICE_NAME' not running"
exit 1
}
#启动方法
start(){
if ( checkRunning );then
PID="`cat $PIDFILE`"
echo "INFO: Process with pid '$PID' is already running"
exit 0
fi
ENVIRONMENT="`cat ${ENVFILE}`"
java -jar -Xms64M -Xmx512M -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5105 -Dspring.config.location=config-${SERVICE_NAME}/application-${ENVIRONMENT}.yml -Dlogging.config=config-${SERVICE_NAME}/log4j2.xml ${SERVICE_NAME}-0.0.1-SNAPSHOT.jar --spring.profiles.active=${ENVIRONMENT} > console.log 2>&1 &
echo $! > "${PIDFILE}";
}
#停止方法
stop(){
if ( checkRunning ); then
PID="`cat ${PIDFILE}`"
echo "INFO: sending SIGKILL to pid '$PID'"
kill -KILL $PID
RET="$?"
rm -f "${PIDFILE}"
return $RET
fi
echo "INFO: not running, nothing to do"
return 0
}
show_help() {
cat << EOF
Tasks provided by the sysv init script:
stop - terminate instance in a drastic way by sending SIGKILL
start - start new instance
restart - stop running instance (if there is one), start new instance
status - check if '$SERVICE_NAME' process is running
EOF
exit 1
}
# show help
if [ -z "$1" ];then
show_help
fi
case "$1" in
status)
status
;;
restart)
if ( checkRunning );then
$0 stop
echo
fi
$0 start
$0 status
;;
start)
start
;;
stop)
stop
exit $?
;;
*)
esac