【shell 脚本】

编写 shell 脚本

Hello word
  • 创建并进入编写一个 xx.sh脚本文件
vi first.sh
#! /bin/bash

echo "Hello Word!"

  • 运行 .sh脚本
sh first.sh

./first.sh

加上 -x 可以查看脚本的运行记录

sh -x first.sh
[root@shell ~]# sh -x first.sh
+ echo 'Hello Word!'

Hello Word!
基础语法

分号,换行都表示单条命令的结束。同一行内写多条命令必须用;分割。

空格。某些结构的语法要求必须有空格,如 $[ $1 -lt 10 ]中,‘[’ 后要有空格,']'前也要空格; 如定义函数 sum() { 后必有空格或换行。如单行内定义多个变量要用空格分割。

‘’ 表示字符串原样。``表示输出其中命令的结果。如echo `seq 1 5`会输出 1 2 3 4 5。

运行和调试

如果某一行语法错误,下面不关联的脚本仍然会继续执行。

使用sh 或 .都能执行shell脚本文件。

调试:

  • -x
    跟踪执行过程,将每条执行命令和结果一并输出。可以检查语法错误,尤其对于单行文本中有多条命令,-x 会将根据语法规则做详细拆分,逐次输出命令和结果。
  • -n
    读一编脚本但不执行,可以用来事先检查语法错误。
  • -v
    将每行命令文本和对应的结果一并输出。
在shell中使用变量
  1. 在shell中定义变量
a=1

echo $a

对变量做数学运算,需要使用[]括起来,并在[]前使用$

a=1
b=2

echo "sum=$[$a+$b]"
  1. 预设变量
a=$1
b=$2

echo "sum=$[$a+$b]"

执行命令同时传入的参数,用$1、$2…对应参数顺序就可以。$0特指当前shell脚本文件名。

[root@shell ~]# sh first.sh 100 200

sum=300
  1. 交互变量,shell运行过程中传入变量
read -p "请输入第一个值:" x
read -p "请输入第二个值:" y

echo "求和等于:$[$x+$y]"

执行脚本:

[root@shell ~]# sh first.sh 
请输入第一个值:100
请输入第二个值:200

求和等于:300
if选择结构
if 不带 else

格式:

if 判断语句
then
    命令语句
fi

示例:

if (($1 < 5))
then
    echo $1这个数小于5
fi

单行内写完整个if结构要使用分号:

if [ $y -gt 100 ];then echo $y大于100哈;fi
if else

格式:

if 判断语句
then
    命令语句
else
    命令语句
fi

示例:

if (($1 < 5)); then
    echo 这个数小于5
else
    echo 这个数太大了
fi
if elif

格式:

if 判断语句; then
    命令语句
elif 判断语句; then
    命令语句
else
    命令语句
fi

示例:

if (($1 < 5)); then
    echo 这个数小于5
elif (($1 == 5)); then
    echo 这个数刚好
else
    echo $1你太大了
fi
-lt、-gt、-le、-ge、-eq、-ne

等值的判断语句可以写在(())内,也可以写在[]内,使用[]时<>=符号要用以下符号代替。

-lt 小于
-gt 大于
-le 小于或等于
-ge 大于或等于
-eq 等于
-ne 不等于
if [ $1 -lt 5 ]; then
    echo 这个数小于5
elif [ $1 -eq 5 ]; then
    echo 这个数刚好
else
    echo 这个数太大了
fi
&& 和 ||

与和或。在判断语句中使用 && 和 || 对多个条件的判断,和java类似。

if [ $1 -lt 5 ] || [ $1 -gt 10 ]; then
    echo 这个数小于5,或大于10
fi
文档相关的判断

在if 判断语句中,对文档的判断,常用的有以下关键字

-e 判断文件或目录是否存在
-d 判断是不是目录以及是否存在
-f 判断是不是文件以及是否存在
-r 判断是否有读权限
-w 判断是否有写权限
-x 判断是否有执行权限
-x 判断字符串为空返回true
-s 判断文件大小不为0返回true

判断文件存在,具体格式:

if [ -e filename ]; then
    命令语句
fi
if [ -e /home/ ]; then
    echo 'ok'
fi
case选择结构

具体格式如下

case 变量 in
value1)
    命令语句
    ;;
value2)
    命令语句
    ;;    
*)
    命令语句
    ;;
esac

示例:

a=$[$1%2]

case $a in
0)
    echo "The number is even."
    ;;
1)
    echo "The numbei is odd."
    ;;
*)
    echo "Tt's not a number."
    ;;
esac
for循环

格式:

for 变量名 in 循环条件; do
    命令语句
done

循环条件可以是一组字符串或数字(空格分割),也可以是一条命令的执行结果。
示例:

for i in 1 2 3 a b c; do
    echo $i;
done
# seq 1 5 表示从1到5的一个序列
for i in `seq 1 5`; do
    echo $i;
done
for file in `ls ~`; do
    echo $file;
done
while循环

格式:

while 条件语句; do
    命令语句
done

示例:

a=$1

while [ $a -ge 1 ]; do
    echo $a
    a=$[$a-1]
done

如果用冒号代替循环条件,可以死循环

while :; do
    echo '呀哈哈,我被发现了'
done
循环中断 break、continue、exit

break 结束整个循环体。
continue 结束本次循环,进入下一次循环。
exit 退出整个脚本。

for i in `seq 1 5`
do
    if [ $i == 3 ]; then
        break
    fi
    echo $i
done
# 输出 1 2
for i in `seq 1 5`
do
    if [ $i == 3 ]; then
        continue
    fi
    echo $i
done
# 输出 1 2 4 5
数组
  • 定义数组
a=(1 2 3 4 5)

或者

a=(`seq 1 5`)
  • 获取数组所有元素
echo ${a[@]}

或者

echo ${a[*]}
  • 获取数组长度
echo ${#a[@]}
  • 获取指定索引的元素
echo ${a[1]}
  • 修改指定索引的元素
a[1]=100  
# 1 100 3 4 5
  • 直接替换指定位置元素
# 将第3个元素设置为100. 注意,3不是索引
a=(${a[@]/3/100})
# 1 100 100 4 5
# 如果索引下标不存在,则添加一个元素
a[5]=6
# 1 100 3 4 5 6 
  • 删除指定索引的元素
unset a[5]
# 1 100 3 4 5
  • 删除整个数组
unset a
  • 指定位置和长度截取
# 从索引第0个元素开始,截取长度3个
echo ${a[@]:0:3} 
# 1 2 3
# 从倒数第3个元素开始,截取长度2个
echo ${a[@]:0-3:2} 
# 3 4
函数定义和使用

定义函数必须写在调用函数之前,而且是在最前,不能出现在中间。
示例:

# 定义sum()函数
function sum()
{
    sum=$[$1+$2]
    echo $sum
}

# 调用
sum $1 $2 
在shell中使用日期date
#! /bin/bash

date

运行后输出:

2023年04月11日 星期二 15:11:38 CST

如果要将date执行结果赋值给变量,需要写在``中,否则表示date这个字符串

d=`date`
echo $d
  • 指定格式的日期
%Y 表示四位数字年份
%y 表示两位数字年份
%m 表示月份
%d 表示日期
%H 表示小时
%M 表示分钟
%S 表示秒
%w 表示星期

示例:

date +%Y-%m-%d
# 2023-04-12

示例:

date +'%Y-%m-%d %H:%M:%S'
# 2023-04-12 17:49:43

注意区分大小写,在java中输出这个样式是使用 yyyy-MM-dd HH:mm:ss

  • 对日期加减偏移
date -d '-1 day' # 当前日期的前一天
date -d '-1 hour' # 当前时间的前一小时
date -d '-1 min' # 当前日期的前一分钟

偏移后的日期仍然可以指定格式输出

date -d '-1 day' +'%Y-%m-%d %H:%M:%S'

同样,赋值给变量也需要写在``里

d1=`date -d '+1 hour' +'%Y-%m-%d %H:%M:%S'`
echo $d1

bin/bash 和 /bin/sh

以/bin/bash声明的脚本,中间即使发生错误,依然会继续向下运行。
/bin/sh是早期版本,脚本中间发生错误会终止脚本的运行,不再运行下面的代码。

#!/bin/bash --posix,脚本执行效果跟#!/bin/sh是一样的。

#!/bin/bash  --posix  #开启便携模式,遇到错误时,停止继续运行

新版本的Linux内核中,老的sh已经被后来者bash整合了。

你可能感兴趣的:(Linux,shell)