shell脚本

一、shell概述

shell 的两层含义:既是一种应用程序,又是一种程序设计语言
作为应用程序:交互式地解释、执行用户输入的命令,将用户的操作翻译成机器可以识别的语言,完成相应功能,因而又可称为shell命令解析器。

shell 是用户和 Linux 内核之间的接口程序

1、用户在提示符下输入的命令都由 shell 先解释然后传给 Linux 核心;

2、它调用了系统核心的大部分功能来执行程序、并以并行的方式协调各个程序的运行;

3、Linux 系统中提供了好几种不同的 shell 命令解释器,如 sh、ash、bash 等。一般默认使用 bash 作为默认的解释器;

4、shell 是用户跟内核通信几种方式的一种。

作为程序设计语言:它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支完成类似于 windows 下批处理操作,简化我们对系统的管理与应用程序的部署称之为shell 脚本。

shell脚本是shell命令的有序集合

        c/c++等语言,属于编译性语言(编写完成后需要使用编译器完成编译、汇编、链接等过程变为二进制代码方可执行);shell 脚本是一种脚本语言,我们只需使用任意文本编辑器,按照语法编写相应程序,增加可执行权限,即可在安装 shell 命令解释器的环境下执行

shell 脚本主要用于:帮助开发人员或系统管理员将复杂而又反复的操作放在一个文件中,通过简单的一步执行操作完成相应任务, 从而解放他们的负担。

二、shell语法

 2.1 shell 脚本的定义与执行

shell脚本的代码编写流程 

第一步:指定shell脚本文件,一般以.sh作为后缀名,也可以不加,例如:test.sh

第二步:编写代码 
复制代码
#!/bin/bash 
# #!用于指定当前脚本文件的shell解释器的类型,如不写,则用默认的shell
#shell脚本是shell命令的有序集合,代码的构成就是命令

ls 

pwd  

echo "hello world"
复制代码
第三步:修改文件权限 
chmod +x test.sh
第四步:执行脚本文件 
三种执行方式
./test.sh            增加可执行权限后执行
bash test.sh    直接指定使用 bash 解释 test.sh    
. test.sh(或source test.sh) 使用当前 shell 读取解释 test.sh

三种执行脚本的方式不同点:

./ bash 执行过程基本一致,后者明确指定 bash 解释器去执行脚本,脚本中#!指定的解释器不起作用前者首先检测#!,使用#!指定的 shell,如果没有使用默认的 shell

用./ bash 去执行会在后台启动一个新的 shell 去执行脚本

用.去执行脚本不会启动新的 shell,直接由当前的 shell 去解释执行脚本。

2.2 变量

2.2.1 自定义变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/bin/bash
 
#定义变量
#shell脚本中没有数据类型可言,所以定义变量时不需要加数据类型
#shell脚本中,赋值操作时不能在等号两边加空格
#NUM = 100 #错误
NUM=100
 
#引用变量
# $变量名 取一个变量的值
i=$NUM
 
#显示变量
echo $NUM
echo $i
 
#清除变量
unset NUM
echo "*************"
echo $NUM
 
#使用read从终端读取数据保存在变量中
read str
echo "str = $str"
 
#使用readonly创建一个只读的变量
readonly n=999
echo "n = $n"
 
#指定变量初始化后不能再次修改变量的值,只能使用
#n=666
#echo "n = $n"

  

2.2.2 环境变量

shell在开始执行时就已经定义了一些和系统的工作环境有关的变量,我们在shell中可以直接使用$name引用
一般在~/.bashrc或/etc/profile文件中(系统自动调用的脚本)使用export设置,允许用户后来更改
设置环境变量:
方法1:临时设置
在终端执行命令 
MYVAL=999 
export MYVAL
方法2:永久设置
需要在配置文件(~/.bashrc或/etc/profile)中进行设置即可,设置完毕后需要通过source命令配置文件立即生效
使用环境变量,一般环境变量类似c语言中的全局变量,可以再shell脚本文件中任意使用 
#!/bin/bash 

echo "You are welcome to use bash" 
echo "Current work dirctory is $PWD" 
echo "the host name is $HOSTNAME" 
echo "your home dir $HOME" 
echo "Your shell is $SHELL" 
echo "user env val is $MYVAL1"

2.2.3 预设变量

$#:传给shell脚本参数的数量
$*:传给shell脚本参数的内容
$1、$2、$3、...、$9:运行脚本时传递给其的参数,用空格隔开
$?:命令执行后返回的状态
"$?"用于检查上一个命令执行是否正确(在Linux中,命令退出状态为0表示该命令正确执
行,任何非0值表示命令出错)。
$0:当前执行的进程名
$$:当前进程的进程号
"$$"变量最常见的用途是用作临时文件的名字以保证临时文件不会重复 
复制代码
#! /bin/bash 
#位置变量$0 ‐ $9 保存从终端输入的每一个参数 
echo "\$0 = $0" 
echo "\$1 = $1" 
echo "\$2 = $2" 
echo "\$5 = $5" 
echo "\$6 = $6" 
echo "\$7 = $7" 
echo "\$8 = $8" 
echo "\$9 = $9" 
#如果超过9,需要加大括号 
echo "\$10 = ${10}" 

#$#:保存命令行传入的参数的个数,不包括$0 
echo "\$# = $#" 

#$@或者$*:保存所有的命令行传入的参数,但是不包括$0
echo "\$@ = $@"
echo "\$* = $*"

#$$:获取当前进程的进程号
echo "\$$ = $$"
#read NUM

# $? 返回上一个命令执行的结果,如果执行成功,则$?的值为0,执行失败,则为非0
ls
echo "\$? = $?"

ls asdfasdf
echo "\$? = $?" 
复制代码

2.2.4 脚本变量的特殊用法

""(双引号):包含的变量会被解释
''(单引号):包含的变量会当做字符串解释
``(数字键1左面的反引号):反引号中的内容作为系统命令,并执行其内容,可以替换输出为一个变量
$ echo "today is `date` "
today is 2012年07月29日星期日 12:55:21 CST
\ 转义字符:同c语言 \n \t \r \a等 echo命令需加-e转义
(命令序列):由子shell来完成,不影响当前shell中的变量
{ 命令序列 }:在当前shell中执行,会影响当前变量 
复制代码
#!/bin/bash 

name="zhangsan" 
#双引号里面的特殊字符,会使用其特殊含义 
string1="good moring $name" 
#单引号里面的特殊字符,都会失去特殊含义 
string2='good moring $name' 

echo $string1 
echo $string2 
#反引号:获取一个shell命令的输出结果,一般对有输出结果的命令经常去使用,也可以使用$()与反引号等价 echo
"today is date" echo "today is `date`" echo 'today is `date`' echo "My dir is $(ls)"
#转义字符:使用时,需要在echo后面加上‐e选项 echo
"**************" echo "this \n is\ta\ntest" echo ‐e "this \n is\ta\ntest" echo "**************"
num
=100 #由子shell来完成,不影响当前shell中的变量 ( num=999;echo "1 $num" ) echo 1:$num #在当前shell中执行,会影响当前变量 { num=666; echo "2 $num"; } echo 2:$num
复制代码

2.3 条件测试语句

在写shell脚本时,经常遇到的问题就是判断字符串是否相等,可能还要检查文件状态或进行数字测试,只有这些测试完成才能做下一步动作
test命令:用于测试字符串、文件状态和数字
test命令有两种格式:
test condition 或 [ condition ]
使用方括号时,要注意在条件两边加上空格
shell脚本中的条件测试如下:
文件测试、字符串测试、数字测试、复合测试
测试语句一般与后面讲的条件语句联合使用 

2.3.1 文件测试

1)按照文件类型
-e 文件名 文件是否存在
-s 文件名 是否为非空
-b 文件名 块设备文件
-c 文件名 字符设备文件
-d 文件名 目录文件
-f 文件名 普通文件
-L 文件名 软链接文件
-S 文件名 套接字文件
-p 文件名 管道文件 
 
2)按照文件权限
-r 文件名 可读
-w 文件名 可写
-x 文件名 可执行
 
3)两个文件之间的比较
文件1 -nt 文件2 文件1的修改时间是否比文件2新
文件1 -ot 文件2 文件1的修改时间是否比文件2旧
文件1 -ef 文件2 两个文件的inode节点号是否一样,用于判断是否是硬链接
复制代码
#! /bin/bash 

echo "please input a filename >>> " 
read FILE 
test ‐e $FILE 
echo "存在?$?" 
 
test ‐s $FILE 
echo "非空?$?" 

[ ‐r $FILE ] 
echo "可读?$?" 

[ ‐w $FILE ] 
echo "可写?$?" 

[ ‐x $FILE ] 
echo "可执行?$?" 

test ‐b $FILE 
echo "块设备文件?$?"

test ‐c $FILE 
echo "字符设备文件?$?" 

test ‐d $FILE 
echo "目录文件?$?" 

test ‐f $FILE 
echo "普通文件?$?"

test ‐L $FILE 
echo "软链接文件?$?" 

test ‐S $FILE 
echo "套接字文件?$?" 

test ‐p $FILE 
echo "管道文件?$?"
复制代码
2.3.2 字符串测试
s1 = s2 测试两个字符串的内容是否完全一样
s1 != s2 测试两个字符串的内容是否有差异
-z s1 测试s1 字符串的长度是否为0
-n s1 测试s1 字符串的长度是否不为0
复制代码
#! /bin/bash
 
test "hello" = "hello" 
echo "相等?$?" 

test "hello" = "hella" 
echo "相等?$?" 

test "hello" != "hello" 
echo "不相等?$?" 

test "hello" != "hella" 
echo "不相等?$?" 

test ‐z "hello" 
echo "长度是否为0?$?" 

test ‐n "hello" 
echo "长度是否不为0?$?"
复制代码

 2.3.3 数字测试

a -eq b  测试a 与b 是否相等
a -ne b  测试a 与b 是否不相等
a -gt b   测试a 是否大于b
a -ge b  测试a 是否大于等于b
a -lt b    测试a 是否小于b
a -le b   测试a 是否小于等于b
复制代码
#! /bin/bash 

echo "please input two numbers >>> " 
read NUM1 NUM2 

test $NUM1 ‐eq $NUM2 
echo "相等?$?" 
test $NUM1 ‐ne $NUM2 
echo "不相等?$?" 

test $NUM1 ‐gt $NUM2 
echo "大于?$?" 

test $NUM1 ‐ge $NUM2 
echo "大于等于?$?" 
 
test $NUM1 ‐lt $NUM2 
echo "小于?$?" 

test $NUM1 ‐le $NUM2 
echo "小于等于?$?"
复制代码
2.3.4 复合测试
第一种形式:命令执行控制
&&:command1 && command2
&&左边命令(command1)执行成功(即返回0)shell才执行&&右边的命令(command2)
||:command1 || command2
||左边的命令(command1)未执行成功(即返回非0)shell才执行||右边的命令(command2)
第二种形式:多重条件判定

-a

(and)两状况同时成立!

test -r file -a -x file

file 同时具有 r x 权限时,才为 true.

-o

(or)两状况任何一个成立!

test -r file -o -x file

file 具有 r x 权限时,就传回 true.

!

相反状态

test ! -x file

file 不具有 x 时,回传 true.

复制代码
#! /bin/bash 

num=100 

#判断 0 <= num <= 200 
#test $num ‐ge 0 && test $num ‐le 200 
test $num ‐ge 0 ‐a $num ‐le 200 
echo "$?" 

#判断 num <= 0 或者 num >= 200 
test $num ‐le 0 || test $num ‐ge 200
echo "$?" 

file="file.txt" 

#判断文件是否不是普通文件 
test ! ‐f $file 
echo "$?" 
#判断文件是否存在并且是否是目录文件 test ‐e $file
&& test ‐d $file echo "$?"
复制代码

 

 
 

  

 
 
posted @   while19  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示