linux 系统上 shell脚本 的写法(循环的写法)

linux 系统上 shell脚本 的 使用介绍(循环的写法)

shell脚本介绍

shell脚本:是linux上的一种脚本语言,
有三种格式:

#!/bin/sh 
#!/bin/bash
#!/bin/ksh(使用比较少)

格式必须出现在shell脚本的第一行。
shell脚本中包含流程控制语句和linux命令,变量等内容
shell脚本文件的名字一般以.sh结尾,也可以没有后缀

写一个简单的shell脚本

[root@ ~]# vim first.sh

#!/bin/bash
echo Hello World

shell脚本的运行:
1.给脚本文件赋可执行权限
chmod 755 first.sh
2.运行脚本
(1)使用sh命令运行脚本
sh first.sh #可以使用脚本的绝对路径 ,如果脚本没有格式字符串,使用sh可以运行
(2) 进入脚本文件所在的目录,使用./运行脚本
./first.sh #只能在脚本文件目录下运行脚本,如果脚本没有格式字符串,那么不一定能正常运行

shell脚本的参数:

$0:表示取脚本的名称
$n:n表示一个自然数(1到9),表示取脚本的第n个参数
$#:表示取脚本的参数个数
$*:表示取脚本的所有参数
$?:取上一个命令的运行结果(是一个数字,一般0和1,也可以是其他数据)

shell脚本的传参

shell脚本的传参:在运行脚本时,在脚本后面加上空格,后面就是脚本的参数,参数和参数之间用空格隔开

[root@ ~]# vim param.sh

#!/bin/bash
echo '打印脚本的名称$0:'$0
echo '打印脚本的第1个参数$1:'$1
echo '打印脚本的第2个参数$2:'$2
echo '打印脚本的第3个参数$3:'$3
echo '打印脚本的参数个数$#:'$#
echo '打印脚本的所有参数$*:'$*

[root@bow ~]# chmod 755 param.sh
[root@bow ~]# sh param.sh a b c d e f
打印脚本的名称$0:param.sh
打印脚本的第1个参数$1:a
打印脚本的第2个参数$2:b
打印脚本的第3个参数 3 : c 打 印 脚 本 的 参 数 个 数 3:c 打印脚本的参数个数 3:c#:6
打印脚本的所有参数$:a b c d e f
[root@bow ~]# ./param.sh 1 2 3 4 5 6
打印脚本的名称$0:./param.sh
打印脚本的第1个参数$1:1
打印脚本的第2个参数$2:2
打印脚本的第3个参数 3 : 3 打 印 脚 本 的 参 数 个 数 3:3 打印脚本的参数个数 3:3#:6
打印脚本的所有参数$
:1 2 3 4 5 6
在这里插入图片描述

$符号:取变量的值
${变量名}或者$变量名

变量的定义:
变量名=值

shell脚本中默认的数据类型是字符串类型:

1.字符串的表示:

   (1)不加任何符号
   (2)加单引号,单引号字符串中$等符号,表示一个普通的符号
   (3)加双引号,双引号中的$符号可以取到变量的值

[root@bow ~]# vim str.sh

#!/bin/bash
#声名一个变量
a=hello
#使用单引号
echo '打印变量a的值:$a'
#使用引号
echo "打印变量a的值:$a"
#使用$变量取值
echo 打印变量a的值:$asmith
#使用${}取值的区别
echo 打印变量a的值:${a}smith

[root@ ~]# sh str.sh
打印变量a的值:$a
打印变量a的值:hello
打印变量a的值:
打印变量a的值:hellosmith

2.声名数字类型变量的方法:

[root@bow ~]# a=1+2
[root@bow ~]# echo $a
1+2
(1)使用let得到一个数学表达式的结果
[root@bow ~]# let b=1+2
[root@bow ~]# echo $b
3
(2)使用declare -i来声名一个数字类型的变量
[root@bow ~]# declare -i c
[root@bow ~]# c=1+2
[root@bow ~]# echo c 3 ( 3 ) 使 用 c 3 (3)使用 c3(3)使((数学表达式))来获取一个数学表达式的运算结果
[root@bow ~]# d=$((1+2*2))
[root@bow ~]# echo $d
5

3.日期在shell中只能通过字符串来表示

date命令,获取当前系统的日期和时间
%Y:表示年
%m:表示月
%d:表示天
%H:表示小时
%M:表示分钟
%S:表示秒
%A:表示星期

[root@bow ~]# date '+%Y-%m-%d %H:%M:%S'
[root@bow ~]# date '+%Y-%m-%d %H:%M:%S %A'
2020-03-30 10:47:55 星期一
修改日期:
[root@bow ~]# date -s 2020-03-31
2020年 03月 31日 星期二 00:00:00 CST

[root@bow ~]# date -s 14:34:31
2020年 03月 31日 星期二 14:34:31 CST

[root@bow ~]# date -s 2020-03-30
2020年 03月 30日 星期一 00:00:00 CST
[root@bow ~]# date -s 10:52:30
2020年 03月 30日 星期一 10:52:30 CST
``:取一个命令的运行结果(注意它不是单引)
[root@bow ~]# d=`date '+%Y%m%d %H:%M:%S'`
[root@bow ~]# echo $d
20200330 10:55:09

流程控制语句:

(1)if语句

if 条件表达式; then
脚本内容(linux命令)
fi
if 条件表达式
then
脚本内容
fi

条件表达式:
 符号:[],[[]],(())

[]:里面可以放大部分的条件表达式,(尽量不要使用数学上的判断符号:>,<,=,!=)
[[]]:里面可以放[]中的所有条件,也可以对数字类的条件
(()):里专用于数学条件表达式里面可以使用(+,-,*,/,>,<,>=,<=,!=)

条件比较符号:
 (1)数字类型的
     -eq(equals)表示等于
     -lt:(less than)表示小于
     -gt:(grate than)表示大于
     -le:(less equals)表示小于等于
     -ge:(grate equals)表示大于等于
     -ne:(not equals)表示不等于

  (2)字符串类
     -n :表示非空,字符串不为空时,返回true,否则返回false
     -z :和-n相反,当字符串为空时,返回true,否则返回false

    
 (3)文件类型的
     -e :判断路径是否存在,路径存在返回true,否则返回false
     -f :判断它是否是一个文件,如果是文件返回true,否则返回false
     -d :判断它是否是一个目录, 如果是目录返回true,否则返回false
!:表示取反
注意:在[][[]]中所有的符号和变量之间必须至少有一个空格

      [][[]]里面使用>,<,>=,<=这些条件不能保证正确
      (())里面不需要空格
[root@bow ~]# [ "aaa" == "bbb" ]
[root@bow ~]# echo $?
1
[root@bow ~]# [ "aaa" == "aaa" ]
[root@bow ~]# echo $?
0
[root@bow ~]# [ 3 -eq 4 ]
[root@bow ~]# echo $?
1
[root@bow ~]# [ 3 -eq 3 ]
[root@bow ~]# echo $?
0
[root@bow ~]# [ ! "aaa" == "bbb" ]
[root@bow ~]# echo $?
0
[root@bow ~]# [[ 3 -gt 2 ]]
[root@bow ~]# echo $?
0
[root@bow ~]# a=123
[root@bow ~]# b=234
[root@bow ~]# [ "$a" -gt "$b" ]
[root@bow ~]# echo $?
1
[root@bow ~]# [ "$a" -lt "$b" ]
[root@bow ~]# echo $?
0

[root@bow ~]# d=abcd
[root@bow ~]# [ -n "$d" ]
[root@bow ~]# echo $?
0
[root@bow ~]# [ -n "$e" ]
[root@bow ~]# echo $?
1

[root@bow ~]# [ -e /root/1.txt ]
[root@bow ~]# echo $?
1
[root@bow ~]# [ -e /root/first.sh ]
[root@bow ~]# echo $?
0

[root@bow ~]# [ -f /root ]
[root@bow ~]# echo $?
1
[root@bow ~]# [ -f /root/str.sh ]
[root@bow ~]# echo $?
0
[root@bow ~]# [ -d /root ]
[root@bow ~]# echo $?
0
[root@bow ~]# [ -d /root/str.sh ]
[root@bow ~]# echo $?
1

[[]]比[]通用

条件连接符
-a :(and)表示并且
-o :(or) 表示或者

&& :表示并且
|| :表示或者
(()),[[]]里面条件只能使用&&或||连接,[]里面使用-a或-o来连接

[root@bow ~]# [ 1 == 1 -a 2 == 2 ]
[root@bow ~]# echo $?
0
[root@bow ~]# [ 1 == 1 -a 2 == 3 ]
[root@bow ~]# echo $?
1
[root@bow ~]# [ 1 == 1 -o 2 == 3 ]
[root@bow ~]# echo $?
0
[root@bow ~]# [[ 1 -eq 1 && 2 -eq 2 ]]
[root@bow ~]# echo $?
0
[root@bow ~]# [[ 1 -eq 1 || 3 -eq 2 ]]
[root@bow ~]# echo $?
0
[root@bow ~]# ((3>4))
[root@bow ~]# echo $?
1
[root@bow ~]# ((3<=4))
[root@bow ~]# echo $?
0
[root@bow ~]# ((3<=4&&2==3))
[root@bow ~]# echo $?
1
[root@bow ~]# ((3<=4||2==3))
[root@bow ~]# echo $?
0
read命令

read命令从键盘接收一个输入值放入变量中
read 变量
read -p 提示信息 变量

[root@bow ~]# vim if.sh

#!/bin/bash
#read命令从键盘上读取一个输入值,放入一个变量中 使用方法:read 变量名
echo -n 请输入一个值
read v
if [ $v -lt 18 ];then
   echo 未成年
fi
#!/bin/bash
#read命令从键盘上读取一个输入值,放入一个变量中 使用方法:read 变量名
read -p 请输入一个值 v
if [ $v -lt 18 ]
then
   echo 未成年
fi
[root@bow ~]# chmod 755 if.sh
[root@bow ~]# sh if.sh
请输入一个值12
未成年
[root@bow ~]# sh if.sh
请输入一个值20

(2)ifelse语句

if 条件表达式;then

else

fi
if 条件表达式
then

else

fi

[root@bow ~]# vim else.sh

#!/bin/bash
#传入一个参数判断如果参数不存在,那么打印请传入参数,如果传入参数打印参数的值
if [ $# -lt 1 ];then
  echo 请传入参数
else
  echo $1
fi

[root@bow ~]# chmod 755 else.sh
[root@bow ~]# sh else.sh
请传入参数
[root@bow ~]# sh else.sh smith
smith

(3)elif语句

if 条件表达式;then
   ...
elif 条件表达式;then
   ...
elif 条件表达式; then
   ...
else
   ...
fi
if 条件表达式
then
  ...
elif 条件表达式
then
  ...
....
else
  ...
fi

[root@bow ~]# vim elif.sh

#!/bin/bash
#将分数保存到变量score中
score=$1

if ((score<60));then
  echo E
elif ((score<70));then
  echo D
elif ((score<80));then
  echo C
elif ((score<90));then
  echo B
else
  echo A
fi
[root@bow ~]# sh elif.sh
请传入一个学生分数
[root@bow ~]# sh elif.sh 60
D
[root@bow ~]# sh elif.sh 45
E
[root@bow ~]# sh elif.sh 80
B

(4)case语句

case 表达式 in):
   分支代码
;;):
   分支代码
;;
...
*):
   ...
esac

*:表示匹配任意结果(任意多个任意字符),相当于else
[]:表示匹配一个字符 例如:[abc]表示匹配a,b,c三个字母中的任意一个

[root@bow ~]# vim case.sh

#!/bin/bash
if [ $# -lt 1 ];then
  echo 请传入一个课程名称
  exit
fi
course=$1
case $course in
[Cc]hinese):
   echo 语文
;;
M*th):
   echo 数学
;;
[Ee]glish):
   echo 英语
;;
etl):
   echo ETL
;;
oracle):
   echo oracle数据库
;;
*):
   echo 其他课程
esac
[root@bow ~]# sh case.sh 
请传入一个课程名称
[root@bow ~]# sh case.sh elt
其他课程
[root@bow ~]# sh case.sh Maaath
数学
[root@bow ~]# sh case.sh chinese
语文
[root@bow ~]# sh case.sh Chinese
语文
[root@bow ~]# sh case.sh Cchinese
其他课程

(5)until循环

until 条件表达式
do
循环体语句
done
until的条件表达式是退出循环条件

[root@bow ~]# vim until.sh

#!/bin/bash
#声名一个循环变量
i=1
until ((i>9)) #[ $i -gt 9 ]
do
  #打印i的值
  echo $i
  #循环控制语句
  let i=$i+1; #i=$((i+1)) #declare -i i=$i+1
done 

[root@bow ~]# chmod 755 until.sh
[root@bow ~]# sh until.sh
1
2
3
4
5
6
7
8
9

(7)for循环

for 变量 in 集合
do
循环体语句
done
集合:表示和脚本的参数格式相同

for循环遍历一个集合
[root@bow ~]# vim for1.sh

#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9
do
   echo $i
done

[root@bow ~]# chmod 755 for1.sh
[root@bow ~]# sh for1.sh
1
2
3
4
5
6
7
8
9

for循环遍历一个文件目录
[root@bow ~]# vim for2.sh

#!/bin/bash
for f in /root/*  #/root/*表示/root目录下的所有文件或目录
do
   echo $f
done

[root@bow ~]# chmod 755 for2.sh
[root@bow ~]# sh for2.sh
/root/case.sh
/root/elif.sh
/root/else.sh
/root/first.sh
/root/for1.sh
/root/for2.sh
/root/if.sh
/root/param.sh
/root/str.sh
/root/until.sh
/root/while.sh

for循环遍历脚本参数
[root@bow ~]# vim for3.sh

#!/bin/bash
for p in $*
do
   echo $p
done

[root@bow ~]# chmod 755 for3.sh
[root@bow ~]# sh for3.sh
[root@bow ~]# sh for3.sh a b c d e f g
a
b
c
d
e
f
g

for循环遍历目录下的所有txt文件
[root@bow ~]# vim for4.sh

#!/bin/bash
#遍历目录下的txt文件
for f in /root/*.txt
do
  echo $f
done

[root@bow ~]# chmod 755 for4.sh
[root@bow ~]# sh for4.sh
/root/1.txt
/root/2.txt
/root/3.txt
/root/4.txt

for((变量=初始值;循环条件;循环控制语句)) #只支持数字
do
循环体语句
done

[root@bow ~]# vim for5.sh

#!/bin/bash
for ((i=1;i<=9;i=i+1))
do
   echo $i
done

[root@bow ~]# chmod 755 for5.sh
[root@bow ~]# sh for5.sh
1
2
3
4
5
6
7
8
9

shell脚本读写文件

写文件使用 命令 >>文件路径
[root@bow ~]# vim for6.sh

#!/bin/bash
for ((i=1;i<=9;i++))
do
   echo $i >> 5.txt
done
[root@bow ~]# chmod 755 for6.sh
[root@bow ~]# sh for6.sh 
[root@bow ~]# cat 5.txt
1
2
3
4
5
6
7
8
9

读文件
while read 变量 #变量里每次循环会取到文件的一行数据
do
循环体语句
done < 文件路径

[root@bow ~]# echo smith >> 6.txt
[root@bow ~]# echo scott >> 6.txt
[root@bow ~]# echo tom >> 6.txt
[root@bow ~]# echo lucy >> 6.txt
[root@bow ~]# echo zs >> 6.txt
[root@bow ~]# vim f2.sh

while循环读取文件
#!/bin/bash
while read line
do
   echo $line
done < /root/6.txt

[root@bow ~]# chmod 755 f2.sh
[root@bow ~]# sh f2.sh
smith
scott
tom
lucy
zs

for循环读取文件
for 变量 in cat 文件路径
do
循环体
done

[root@bow ~]# vim f3.sh

#!/bin/bash
for line in `cat /root/6.txt`
do
  echo $line
done

[root@bow ~]# chmod 755 f3.sh
[root@bow ~]# sh f3.sh
smith
scott
tom
lucy
zs

读文件时都会涉及到文件行结束符.

PWD:当前目录路径
IFS:文件行结束符
USER:取当前用户
HOSTNAME:取主机名称
PS1:linux命令行开始格式
\u表示用户 \h表示主机名 \W表示当前目录名 \w表示当前目录的绝对路径
#了解内容
 \d :代表日期,格式为weekday month date,例如:“Mon Aug 1”

\H :完整的主机名称

\h :仅取主机名中的第一个名字

\t :显示时间为24小时格式,如:HH:MM:SS

\T :显示时间为12小时格式

\A :显示时间为24小时格式:HH:MM

\u :当前用户的账号名称

\v :BASH的版本信息

\w :完整的工作目录名称

\W :利用basename取得工作目录名称,只显示最后一个目录名

# :下达的第几个命令

$ :提示字符,如果是root用户,提示符为 # ,普通用户则为 $
在PS1中设置字符颜色的格式为:[\e[F;Bm]…[\e[0m],其中“F“为字体颜色,编号为30-37,“B”为背景颜色,编号为40-47,[\e[0m]作为颜色设定的结束。

颜色对照表:

FB颜色
3040黑色
3141红色
3242绿色
3343黄色
3444蓝色
3545紫红色
3646青蓝色
3747白色

只需将对应数字套入设置格式中即可。
  比如要设置命令行的格式为绿字黑底([\e[32;40m]),显示当前用户的账号名称(\u)、主机的第一个名字(\h)、完整的当前工作目录名称(\w)、24小时格式时间(\t),可以直接在命令行键入如下命令
PS2:linux多行命令前的符号

IFS变量的值修改之后,会将linux上的文件结束符修改(原本结束符是\n修改之后,打印一行是不换行的)

[root@bow ~]# vim 7.txt
abc,def,ghi,xyz

#!/bin/bash
#将系统的IFS值保存到bak变量中
bak=$IFS
#设置新IFS值
IFS=',' #字符串的分割
for line in `cat 7.txt`  
do
   echo $line
done
IFS=$bak

[root@bow ~]# sh f4.sh
abc
def
ghi
xyz

IFS:按列读文件时,可以设置列和列之间的间隔符(将一行内容分为多行)
cat 7.txt | cut -f 1 -d ‘,’
cat 7.txt | cut -f 2 -d ‘,’
cat 7.txt | cut -f 3 -d ‘,’
cat 7.txt | cut -f 4 -d ‘,’

有如下8.txt的文件,将文件中的内容插入到一张表中,表的结构同dept表
[root@bow ~]# vim 8.txt
10|oracle|yt
20|python|qd
30|etl|jn
写一个脚本读取8.txt的文件内容,并将第一行的内容分为三个数据

[root@bow ~]# vim f5.sh

#!/bin/bash
while read line
do
   #打印一行内容
   echo $line
   #字符串的截取
   dno=`echo $line | cut -f 1 -d '|'`
   dname=`echo $line | cut -f 2 -d '|'`
   loc=`echo $line | cut -f 3 -d '|'`
   echo 部门编号:$dno
   echo 部门名称:$dname
   echo 部门位置:$loc
   echo -----------------------------------
done < 8.txt
[root@bow ~]# chmod 755 f5.sh
[root@bow ~]# sh f5.sh
10|oracle|yt
部门编号:10
部门名称:oracle
部门位置:yt
-----------------------------------
20|python|qd
部门编号:20
部门名称:python
部门位置:qd
-----------------------------------
30|etl|jn
部门编号:30
部门名称:etl
部门位置:jn
-----------------------------------
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yang_z_1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值