Linux-shell脚本

一、基础语法

1. 简介

shell语言是一门解释性语言,可简单到使用文本编辑器编写,不需要编译,在linux环境中运行,是用户与操作系统交互的一种媒介

常用的shell:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)

查看shell:

echo $SHELL
#结果:/bin/bash

2. 规范

  • shell脚本的命名一般使用英文大小写,以sh为后缀
  • 首行以 !#/bin/bash 开头
  • 变量不能以数字,特殊符号开头,可以使用下划线,不能使用减号-

3. 变量

使用$引用变量,分为系统变量,环境变量,用户自定义变量

3.1 系统变量

$0 	#当前脚本的名称
$n 	#当前脚本的第n个参数,n=1,2,…9
$* 	#当前脚本的所有参数(不包括程序本身)
$# 	#当前脚本的参数个数(不包括程序本身)
$? 	#单个命令执行后返回的状态,用于检查上一个命令执行是否成功,返回0表示执行成功
$$ 	#进程的PID号

3.2 环境变量

全局生效

$PATH  	   #命令所示路径,以冒号为分割;
$HOME  	   #打印用户家目录;
$SHELL 	   #显示当前Shell类型;
$USER  	   #打印当前用户名;
$ID    	   #打印当前用户id信息;
$PWD   	   #显示当前所在路径;
$TERM  	   #打印当前终端类型;
$HOSTNAME  #显示当前主机名;
$PS1       #定义主机命令提示符的;
$HISTSIZE  #历史命令大小,可通过 HISTTIMEFORMAT 变量设置命令执行时间;
$RANDOM    #随机生成一个 0 至 32767 的整数;
$HOSTNAME  #主机名

可在/etc/profile.d/目录创建文件,把软件home目录在文件中创建变量,使用source /etc/profile.d/文件名.sh生效,常见需要配置的有 java,maven环境

3.3 用户自定义变量

用户在脚本中创建的变量,方便维护和管理,只在当前脚本中生效

示例:

#!/bin/bash
a=4
b=20
#加法运算
echo `expr $a + $b`
#减法运算
echo `expr $a - $b`
#乘法运算	注意*号前面要加反斜杠\
echo `expr $a \* $b`
#除法运算
echo `expr $a / $b`

#运算的另外两种写法
c=$((1 + 2))
echo ${c}

d=$[2 - 1]
echo ${d}

4. 流程控制语句

4.1 if条件语句

# 单分支语句
	if [条件表达式];then
		语句1
	fi

# 双分支if语句
	if [条件表达式];then
		语句1
	else
		语句2
	fi

# 多支条件语句
	if [条件表达式1];then
		语句1
	elif [条件表达式2];then
		语句2
	elif [条件表达式3];then
		语句3
	fi  

逻辑判断运算符:

-f	   #判断文件是否存在 eg: if [ -f filename ];
-d	   #判断目录是否存在 eg: if [ -d dir     ];
-eq	   #等于,应用于整型比较 equal;
-ne	   #不等于,应用于整型比较 not equal;
-lt	   #小于,应用于整型比较 letter;
-gt	   #大于,应用于整型比较 greater;
-le	   #小于或等于,应用于整型比较;
-ge    #大于或等于,应用于整型比较;
-a	   #双方都成立(and) 逻辑表达式 –a 逻辑表达式;
-o	   #单方成立(or) 逻辑表达式 –o 逻辑表达式;
-z	   #空字符串;
-x     #是否具有可执行权限
||     #单方成立;
&&     #双方都成立表达式。

示例:

#!/bin/bash

if [ 2 -gt 1 ];then
    echo "yes!"
else
    echo "no!"
fi

4.2 for循环语句

#写法1,在一行
for 变量名 in 取值列表;do 命令;done


#写法2,代码换行不需要;
for 变量名 in 取值列表
do
  命令
done

#写法3,使用(())双括号,可以支持C语言的一些命令
for((i=1;i<=5;i++));do echo $i;done

示例:

#!/bin/bash

for filename in `ls`
do
if [ -d $filename ];then
    echo "yes!"
else
    echo "no!"
fi
done
#!/bin/bash

for number in $(seq 1 5)
do
echo $number
done

shell脚本中执行命令使用``
seq 1 5 表示从1开始,到5结束

4.3 while循环语句

# 一般用于循环文件
while [表达式]
do
  语句1
done

示例:

#示例 1:在死循环中,满足条件终止循环
N=0
while true; do
  let N++
  if [ $N -eq 5 ]; then
    break
fi
  echo $N
done
#结果: 1 2 3 4
#示例 2:举例子说明 continue 用法
N=0
while [ $N -lt 5 ]; do
  let N++
if [ $N -eq 3 ]; then
  continue
fi
  echo $N
done
#结果: 1 2 4
#示例 3: 打印 1-100 数字
i=0
while ((i<=100))
do
        echo  $i
        i=`expr $i + 1`
done
#结果:略

break 是终止循环
continue 是跳出当前循环

4.4 case选择语句

case 模式名  in
  模式 1)
    命令
    ;;
  模式 2)
    命令
    ;;
*)
不符合以上模式执行的命令
esac

示例:

#!/bin/bash

PS3="Select a number: "
while true; do
select mysql_version in 5.1 5.6 quit;
 do
  case $mysql_version in
  5.1)
    echo "mysql 5.1"
      break
      ;;
  5.6)
    echo "mysql 5.6"
       break
       ;;
  quit)
    exit
    ;;
  *)
    echo "Input error, Please enter again!"
    break
esac
 done
done

select 是一个类似于 for 循环的语句
select语句一般用于选择,常用于选择菜单的创建,可以配合PS3来做打印菜单的输出信息,其语法格式以select…in do开头,done结尾

5. 函数

定义:

function 函数名(){
   命令序列
   [return x]  #使用return或exit可以显示的结束函数
}

#或者
 
函数名 (){
   命令序列
   [return x]  #使用return或exit可以显示的结束函数
}

直接写 函数中调用函数 直接写函数名
同名函数 后一个生效
调用函数一定要先定义
只要先定义了调用的 其他函数定义顺序无关

调用函数:

函数名 [参数1][参数2]

函数体不能写参数,调用参数时,在函数名后按顺序写参数

返回值:

return表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值

函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码

退出状态码必须是0~255,超出时值将为除以256取余;避免方法:可以使用echo打印返回值,函数外使用$(函数名)接收

示例:

#!/bin/bash

function add() {
echo $(($1+$2))
echo `expr $1 + $2`  
}

add 1 2
#!/bin/bash
#使用递归计算阶乘
fact() {
  if [ $1 -eq 1 ] ;then
    echo 1
  else
    local temp=$[$1 - 1]
    local result=$(fact $temp )
    echo $[$1 * $result]
  fi
}
 
##############main###############
read -p"请输入一个正整数:" num
last=`fact $num`
echo "$num的阶乘的结果为:$last"

6. 数组

定义:

# 数组是相同类型的元素按一定顺序排列的集合。
格式:array=(元素 1 元素 2 元素 3 ...)
用小括号初始化数组,元素之间用空格分隔。
 定义方法 1:初始化数组 array=(a b c)
 定义方法 2:新建数组并添加元素 array[下标]=元素
 定义方法 3:将命令输出作为数组元素array=($(command))

示例:

#方法 1:
#!/bin/bash
NUM=(1 2 4 6 90 8 4)
for ((i=0;i<${#NUM[*]};i++)); do
echo ${NUM[$i]}
done


#方法 2:
#!/bin/bash
NUM=(1 2 4 6 90 8 4)
for NUM1 in ${NUM[*]}; do
echo $NUM1
done 

二、常用脚本记录

1. 批量创建用户并设置密码

#!/bin/bash
USER_LIST=$@
USER_FILE=./user.info
for USER in $USER_LIST;do
 if ! id $USER &>/dev/null; then
  PASS=$(echo $RANDOM |md5sum |cut -c 1-8)
  useradd $USER
  echo $PASS | passwd --stdin $USER &>/dev/null
  echo "$USER   $PASS" >> $USER_FILE
  echo "$USER User create successful."
 else
  echo "$USER User already exists!"
 fi
done

2. 查看占用资源过高的进程

#!/bin/bash
echo "-------------------CUP占用前10排序--------------------------------"
ps -eo user,pid,pcpu,pmem,args --sort=-pcpu  |head -n 10
echo "-------------------内存占用前10排序--------------------------------"
ps -eo user,pid,pcpu,pmem,args --sort=-pmem  |head -n 10

3. 一键多台机器执行命令

#! /bin/bash

for i in h1 h2 h3 h4 h5 h6
do
        echo --------- $i ----------
        ssh $i "$*"
done

常用于查看集群的服务或者资源情况:jps,df -h,free -g等

4. 修改文件内容后一键同步多台机器

#!/bin/bash
#1 获取输入参数个数,如果没有参数,直接退出
pcount=$#
if((pcount==0)); then
echo no args;
exit;
fi

#2 获取文件名称
p1=$1
fname=`basename $p1`
echo fname=$fname

#3 获取上级目录到绝对路径
pdir=`cd -P $(dirname $p1); pwd`
echo pdir=$pdir

#4 获取当前用户名称
user=`whoami`

#5 循环
for host in h1 h2
do
        echo ------------------- $host --------------
        rsync -av $pdir/$fname $user@$host:$pdir
done

常用于分布式集群安装时,安装包的分发和配置文件内容的同步

5. 磁盘挂载

#! /bin/bash
disk=${1}        #磁盘目录,例如:/dev/sde/
mountdir=${2}    #需要挂载的目录,例如:/mnt/app/

mkfs -t ext4 -F ${disk}
mkdir -p ${mountdir}
mount ${disk} ${mountdir}
echo "UUID=$(blkid ${disk} | cut -d "\"" -f 2) ${mountdir} ext4 defaults 1 2" >> /etc/fstab
mount -a
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值