Shell介绍
Shell 教程
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。
Shell 脚本
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。
业界所说的 shell 通常都是指 shell 脚本,但读者朋友要知道,shell 和 shell script 是两个不同的概念。
由于习惯的原因,简洁起见,本文出现的 “shell编程” 都是指 shell 脚本编程,不是指开发 shell 自身。
Shell知识点
变量
等号设置变量
变量名=变量内容
$ 读取,单引号中$ 变量名,双引号中$ 变量名、$ {变量名}都可
$ 变量名、$ {变量名}
传递参数
$ n,n代表第几个数字
$ 0 为执行的文件名,其余代表第n个参数
$ n
运算符
算术运算符
+ 加
- 减
* 乘
/ 初
= 赋值
== 相等
!= 不相等
关系运算符
-eq 相等返回 true
-ne 不相等返回 true
-gt >返回 true
-lt <返回 true
-ge >=返回 true
-le <=返回 true
布尔运算符
! 非运算
-o 或运算
-a 与运算
逻辑运算符
&& AND
|| OR
字符串运算符
= 两个字符串相等返回 true [ $a = $b ]
!= 不相等返回 true
-z 字符串长度为0返回 true
-n 字符串长度不为 0 返回 true
$ 字符串s不为空返回 true。
命令
echo,输出字符串
echo string
流程控制
if else-if else
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
for 循环
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
while 语句
while condition
do
command
done
switch case
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
函数
[ function ] funname [()]
{
action;
[return int;]
}
参数
$# 传递到脚本或函数的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
输入/输出重定向
command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command >> file 将输出以追加的方式重定向到 file。
Shell脚本
windows下编译的shell文件,每一行的结尾是\n\r,而在linux下文件的结尾是\n
文件放入linux后,用以下命令解决
$ sed -i 's/\r$//' 文件名
注释版
# export:用于设置或显示环境变量
# export [-fnp][变量名称]=[变量设置值]
export JAVA_HOME=/usr/java/jdk1.8.0_11
export JRE_HOME=$JAVA_HOME/jre
# 变量赋值,反斜杠为转义
# API_NAME+JAR_NAME 包名 第二个参数传jar名称
API_NAME=$2
JAR_NAME=$API_NAME\.jar
# 启动日志名
LOG_NAME=$API_NAME\.log
#PID 代表是PID文件
PID=$API_NAME\.pid
# 方法:使用说明,用来提示输入参数
formatDescription() {
# echo:输出字符串
# -e:开启转义
echo -e "===============Please use the following format==================\n"
echo -e ">>> sh service.sh [start|debug|stop|restart|status] <<<"
echo -e "\n==============================================================="
# exit 0:正常运行程序并退出程序;
# exit 1:非正常运行导致退出程序;
exit 1
}
# 方法:检查程序是否在运行
checkStatus(){
# ps -ef|grep $JAR_NAME 匹配进程中包名
# grep -v 参数 : 过滤 匹配参数
# awk '{print $2}' 匹配第二个参数
# $0 就是你写的shell脚本本身的名字
# $1 是你给你写的shell脚本传的第一个参数
# $2 是你给你写的shell脚本传的第二个参数
pid=`ps -ef|grep $JAR_NAME|grep -v grep|awk '{print $2}' `
# if then、elif then、else、fi
# [ -z STRING ] “STRING” 的长度为零则为真
# 如果不存在返回1,存在返回0
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
# 方法:启动方法
startService(){
# 调用shell内的方法
checkStatus
# $?:获取函数返回值或者上一个命令的退出状态
# -eq : 等于
if [ $? -eq "0" ]; then
echo ">>> ${JAR_NAME} is already running, PID=${pid} <<<"
else
# nohup + & :后台运行
# >$LOG_NAME : 将日志信息输出到log日志中
# 0 表示stdin标准输入
# 1 表示stdout标准输出
# 2 表示stderr标准错误
# & 相当于等效于标准输出
# 2>&1 是将标准错误信息转变成标准输出,这样就可以将错误信息输出到out.log 日志里面来
# -noverify:关闭字节码验证
# java -jar XXX.jar :执行jar
nohup $JRE_HOME/bin/java -noverify -Xms512m -Xmx1024m -jar $JAR_NAME >$LOG_NAME 2>&1 &
# $! Shell最后运行的后台Process的PID
# '>' 为创建: echo “hello shell” > out.txt
# '>>' 为追加:echo “hello shell” >> out.txt
# 将进程的pid输出到.pid文件中(PID=$API_NAME\.pid)
echo $! > $PID
echo ">>> ${JAR_NAME} start successfully, PID=$! <<<"
fi
}
# 方法:debug方法
debugService(){
checkStatus
if [ $? -eq "0" ]; then
echo ">>> ${JAR_NAME} is already running, PID=${pid} <<<"
else
nohup $JRE_HOME/bin/java -agentlib:jdwp=transport=dtSocket,server=y,suspend=n,address=5006 -Xms512m -Xmx1024m -jar $JAR_NAME >$LOG_NAME 2>&1 &
echo $! > $PID
echo ">>> ${JAR_NAME} start in debug mode successfully, PID=$! <<<"
fi
}
# 方法:停止方法
stopService(){
# cat读取PID文件
pidf=$(cat $PID)
#echo "$pidf"
echo ">>> ${JAR_NAME} begin kill, $pidf <<<"
# kill 杀进程
kill $pidf
# rm -rf : 删除文件
rm -rf $PID
# 休眠3s
sleep 3
checkStatus
if [ $? -eq "0" ]; then
echo ">>> kill failed, kill it forcefully <<<"
echo ">>> ${JAR_NAME} begin kill -9 $pid <<<"
# kill -9 强制杀进程
kill -9 $pid
sleep 3
# 无需确认,进程biss
echo ">>> ${JAR_NAME} has been killed <<<"
else
echo ">>> ${JAR_NAME} has stopped <<<"
fi
}
# 方法:重启
restartService(){
stopService
startService
}
# 方法:输出运行状态
statusService(){
checkStatus
if [ $? -eq "0" ]; then
echo ">>> ${JAR_NAME} is running, PID=${pid} <<<"
else
echo ">>> ${JAR_NAME} is not running <<<"
fi
}
# 根据输入参数,选择执行对应方法,不输入则执行使用说明
# case expression in
# pattern 1)
# statement1
# ;;
# pattern 2)
# statement2
# ;;
# ……
# *)
# statementn
# esac
case "$1" in
"start")
startService
;;
"stop")
stopService
;;
"status")
statusService
;;
"restart")
restartService
;;
"debug")
debugService
;;
*)
formatDescription
;;
esac
exit 0
纯净版
export JAVA_HOME=/usr/java/jdk1.8.0_11
export JRE_HOME=$JAVA_HOME/jre
API_NAME=$2
JAR_NAME=$API_NAME\.jar
LOG_NAME=$API_NAME\.log
PID=$API_NAME\.pid
formatDescription() {
echo -e "===============Please use the following format==================\n"
echo -e ">>> sh service.sh [start|debug|stop|restart|status] <<<"
echo -e "\n==============================================================="
exit 1
}
checkStatus(){
pid=`ps -ef|grep $JAR_NAME|grep -v grep|awk '{print $2}' `
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
startService(){
checkStatus
if [ $? -eq "0" ]; then
echo ">>> ${JAR_NAME} is already running, PID=${pid} <<<"
else
nohup $JRE_HOME/bin/java -noverify -Xms512m -Xmx1024m -jar $JAR_NAME >$LOG_NAME 2>&1 &
echo $! > $PID
echo ">>> ${JAR_NAME} start successfully, PID=$! <<<"
fi
}
debugService(){
checkStatus
if [ $? -eq "0" ]; then
echo ">>> ${JAR_NAME} is already running, PID=${pid} <<<"
else
nohup $JRE_HOME/bin/java -agentlib:jdwp=transport=dtSocket,server=y,suspend=n,address=5006 -Xms512m -Xmx1024m -jar $JAR_NAME >$LOG_NAME 2>&1 &
echo $! > $PID
echo ">>> ${JAR_NAME} start in debug mode successfully, PID=$! <<<"
fi
}
stopService(){
pidf=$(cat $PID)
echo ">>> ${JAR_NAME} begin kill, $pidf <<<"
kill $pidf
rm -rf $PID
sleep 3
checkStatus
if [ $? -eq "0" ]; then
echo ">>> kill failed, kill it forcefully <<<"
echo ">>> ${JAR_NAME} begin kill -9 $pid <<<"
kill -9 $pid
sleep 3
echo ">>> ${JAR_NAME} has been killed <<<"
else
echo ">>> ${JAR_NAME} has stopped <<<"
fi
}
restartService(){
stopService
startService
}
statusService(){
checkStatus
if [ $? -eq "0" ]; then
echo ">>> ${JAR_NAME} is running, PID=${pid} <<<"
else
echo ">>> ${JAR_NAME} is not running <<<"
fi
}
case "$1" in
"start")
startService
;;
"stop")
stopService
;;
"status")
statusService
;;
"restart")
restartService
;;
"debug")
debugService
;;
*)
formatDescription
;;
esac
exit 0
格式问题
比如出现这个报错
$'\r': command not found
解决方式:
vi进入文件设置
:set ff=unix
:wq