Shell编程

45 阅读1分钟

[TOC]

Shell编程

第一行

# 声明解释器

#!/bin/bash

注释

# 单行注释
以 # 开头


# 多行注释
以 :<<! 开头,以 ! 结尾

:<<!
echo "Helo"
!

执行

  • 脚本需要可执行权限
chmod u+x /../../xxx.sh
./../../xxx.sh
  • 不需要可执行权限
sh /../../hello.sh

变量

  • 系统变量

    • $HOME
    • $PWD
    • $USER
    • $SHELL
    • ....等
  • 用户自定义变量

  • 显示当前shell中所有系统变量:set

set

用户自定义变

  • 变量名称可以由字母,数字和下划线组成,但是不能以数字开头
  • 等号两侧不能有空格
  • 变量名称一般习惯为大写,这是一个规范
# 定义变量
变量名=值
A=100


# 撤销变量
unset 变量名
unset A


# 输出变量

# $A为前面定义的100
ehco A=$A


# 静态变量,注意:静态变量不能unset
readonly 变量名=值
readonly B=200

image.png

将命令的返回值赋给变量

  • A=`date`反引号,运行里面的命令,把结果返回给变量A

  • A=${date}等价于反引号

image.png

设置环境变量

# 将shell变量输出为环境变量
export 变量名=变量值


# 让修改后的配置信息立即生效
source 配置文件


# 查询环境变量的值
echo $变量名
  • 快速入门

/etc/profile文件中定义 TOMCAT_HOME环境变量

查看环境变量TOMCAT_HOME的值

在另一个shell程序中使用TOMCAT_HOME

注意:在输出TOMCAT_HOME环境变量前,需要让其source /etc/profile

image.png

位置参数变量

./myshell.sh 100 200


$n # n为数字 0代表命令本,$1 - $9代表第1到第9个参数,${10},${11}代表第10个,第11参数

$* # 代表命令行中所有参数,把所有的参数看成一个整体

$@ # 代表命令行中所有参数,$@把每个参数区分对待

$# # 代表参数个数

# 例如:
./myshell.sh 100 200

$0 => ./myshell.sh  $1 => 100 $2 => 200

$* => 100 200

$@ => 100 200

$# => 2

image.png

预定义变量

  • shell 设计者事先定义好的变量,可以直接在shell脚本中使用
# 了解即可

$$ # 当前进程的进程号(PID)

$! # 后台运行的最后一个进程的进程号(PID)

$? # 最后一次执行的命令的返回状态,返回0:上一个命令正确执行,非0:上一个命令执行不正确

运算符

$((运算式)) 或 $[运算式] 或  expr m + n
推荐使用:$[运算式]
注意expr运算符间要有空格,如果希望将expr的结果赋给某一个变量,使用``括起来
expr m -n
expr \*,/,% 乘,除,取余


# 案例1:计算(2+3) × 4 值
SUM = $((  (2+3)*4  ))
SUM = $[ (2+3)*4 ]
RSE = `expr 2 + 3 `
SUM = `expr RSE \* 4`



# 请求出命令行两个参数[整数]的和 20 50
vim myshell.sh
SUM = $[ $1 + $2 ]
echo "SUM = $SUM"

# 退出编辑myshell,并执行
sh ./myshell.sh 20 50

# 输出 => SUM = 70

条件判断

# 基础结构	
if [ 条件 ]
then
   处理
fi


# 多条件结构
if [ 条件判断 ]
then
  代码
elif [ 条件判断 ]
then
  代码
fi


# if 开头 以 fi 结尾

# [ 条件 ] 中括号里条件前后要有空格,没有会报错 

# 非空返回true,可以使用$?验证(0为true,1为false

[ wenzi ] # 返回true
[ ] # 返回false
[ 条件 ] && echo OK || echo notok # 条件满足,执行后面的语句
字符串比较
=
两个整数比较
-lt小于
-le小于等于
-eq等于
-gt大于
-ge大于等于
-ne不等于
按照文件权限进行比较
-r有读的权限
-w有写的权限
-x有执行的权限
按照文件类型进行判断
-f文件存在并且是一个常规的文件
-e文件存在
-d文件存在并且是一个目录

image.png

流程控制

if

if [ 条件判断 ]
then
  代码
fi

或者

if [ 条件判断 ]
then
  代码
elif [ 条件判断 ]
then
  代码
fi

case 语句

case $变量名 in
"值1")
  如果变量的值等于值1,则执行程序1
 ;;
 "值2")
  如果变量的值等于值3,则执行程序3
 ;;
   ...省略其它分之...
 *)
   如果变量的值都不是以上的值,则执行词此程序
;;
esac



# 应用实例 testCase.sh

# 案例1:

# 当命令行参数是1时,输出“周一”,是2时,就输出“周二”,其它情况输出“other”
vim  testCase.sh

#!/bin/bash
case $1 in
"1")
;;
	echo "周一"
"2")
    echo "周二"
;;
*)
   echo "other..."
;;
esac

sh  testCase.sh 1

# => 周一
sh  testCase.sh 2

# => 周二
sh  testCase.sh 3

# => other...

循环

for 循环

# 基本结构
for 变量 in 值1 值2 值3...
do
  程序
done

for ((初始值;循环控制条件;变量变化))
do
  程序
done
  • 应用实例 testFor1.sh
# 应用实例 testFor1.sh

# 案例1:打印命令行输入参数 [这里可以看出 $∗ 和 $@ 区别]

for i in "$*"
do
  echo "num is $i"
done
=========
for i in "$@"
do
  echo "num is $i"
done


sh testFor1.sh 100 200 300 


# 控制台输出
num is 100 200 300 
=========
num is 100
num is 200
num is 300
  • 应用实例 testFor2.sh
# 应用实例 testFor2.sh

# 案例1:从1加到100的值输出显示
SUM=0
for ((i=0;i < 100;i++))
do
  SUM=$[ $SUM + $i ]
done
echo "SUM=$SUM"

sh testFor2.sh

# => SUM=5050


# 通过输入决定从1加到100
SUM=0
for ((i=$1;i < $2;i++))
do
  SUM=$[ $SUM + $i ]
done
echo "SUM=$SUM"

sh testFor2.sh 1 100

# => SUM=5050

while 循环

  • while 和 [ 有空格
  • 条件判断和 [ 也有空格
# 基本结构
while [ 条件判断 ]
do
  程序
done


# 应用实例 testWhile.sh

# 案例1:从命令行输入一个数n,统计从1 +...+n的值是多少?
SUM=0
i=0
while [ $i -le $1 ]
do
  SUM=$[ $SUM+$i]
  i=$[ $i+1 ]
done
echo "SUM=$SUM"
sh testWhile.sh 100

# => SUM=5050

read 读取控制台输入

read(选项)(参数)
-p # 指定读取值的提示符
-t # 指定读取值时等待的时间(秒),如果没有在指定的时间内输入,就不再等待了。


# 案例1:读取控制台输入一个NUM1值
read -p "请输入一个NUM1:" $NUM1
echo "你输入的NUM1=$NUM1"


# 案例2:读取控制台输入一个NUM2值,在10秒内输入
read -t 10 -p "请输入一个NUM2:" $NUM2
echo "你输入的NUM2=$NUM2"

函数

  • 系统函数
  • 自定义函数

获取文件名 (basename)

# basename基本语法

# 返回完整路径最后/的部分,常用于获取文件名
basename [pathname] [suffix]
basename [string] [suffix]

suffix为后缀,如果suffix被指定了,basename会将pathname或者string中的suffix去掉


# 应用实例
basename /home/aa/bb/ccname.txt 
ccname.txt 
basename /home/aa/bb/ccname.txt  .txt
ccname

获取路径 (dirname)

# dirname基本语法

# 返回完整路径最后/的前面的部分,常用于返回路径部分

# 从给定的巴汗绝对路径的文件名中去除文件名(非目录部分),然后返回剩下的路径(目录部分)
dirname 文件绝对路径 


# 应用实例
dirname /home/aa/bb/ccname.txt 
/home/aa/bb

自定义函数

# 基本结构
[ function ] funname[()]
{
  action;
  [return int;]
}
调用直接写函数名:funname [值]


# 应用实例 getSum.sh

# 案例1:计算输入两个参数的和(动态获取),getSum.sh

#!/bin/bash
function getSum() {
	SUM=$[ $1+$2 ]
	echo "SUM=$SUM"
}
read -p "请输入一个NUM1:" $NUM1
read -p "请输入一个NUM2:" $NUM2
getSum $NUM1 $NUM2

sh getSum.sh

# 请输入一个NUM1:10

# 请输入一个NUM2:90

# SUM=100

shell编程综合案例