Shell 是一个命令行解释器,它为用户提供了一个向 Linux 内核发送请求以便运行程序
的界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至是编写一些程序。

操作系统内核(kernel)与shell是独立的套件,而且都可被替换: 不同的操作系统使用不同的shell; 同一个kernel之上可以使用不同的shell。

一.Shell脚本解释器
Linux的Shell脚本解释器种类众多,一个系统可以存在多个shell脚本解释器,可以通过cat /etc/shells 命令查看系统中安装的shell脚本解释器。

1 [root@localhost shell]# cat /etc/shells
2 /bin/sh
3 /bin/bash
4 /usr/bin/sh
5 /usr/bin/bash

bash由于易用和免费,在日常工作中被广泛使用。同时,Bash也是大多数Linux系统默认的Shell脚本解释器。


二.shell 脚本的执行方式

1 [root@localhost shell]# echo "helloworld"
2 helloworld

第一个shell脚本

创建 helloworld.sh文件

 1 [root@localhost shell]# cat helloworld.sh
 2 #!/bin/bash
 3 echo "helloworld"
 4 [root@localhost shell]# chmod +x helloworld.sh    //赋予执行权限 ,如果使用sh命令方式执行,可以省略
 5 [root@localhost shell]# ./helloworld.sh
 6 helloworld

1 输入脚本的绝对路径或相对路径
/root/helloworld.sh
./helloworld.sh
2 bash或sh +脚本
bash helloworld.sh
sh helloworld.sh
source helloworld.sh

三.变量

语法格式:变量名=变量值

(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头。
(2)等号两侧不能有空格
(3)变量名称一般习惯为大写
(4)双引号和单引号有区别,双引号仅将空格脱意,单引号会将所有特殊字符脱意
案例
STR=“hello world”
A=8 定义变量A
unset A 撤销变量A
readonly B=2 声明静态的变量B=2,不能unset
export变量名 可把变量提升为全局环境变量,可供其他shell程序使用
[root@localhost shell]# A=8
[root@localhost shell]# echo $A
8

将一个命令的执行结果赋给变量 A=`ls -la` 反引号,运行里面的命令,并把结果返回给变量A A=$(ls -la) 等价于反引号
设置环境变量
1)基本语法:
export 变量名=变量值 (功能描述:设置环境变量的值)
echo $变量名 (功能描述:查询环境变量的值)
source 配置文件 (功能描述:让修改后的配置信息立即生效) 
2)案例:
在/etc/profile 文件中定义 JAVA_HOME 环境变量
export JAVA_HOME=/opt/module/jdk1.7.0_79
export PATH=$PATH:$JAVA_HOME/bin
查看环境变量
[root@localhost shell]# echo $PWD
/root/shell

四.参数传递

在执行Shell脚本时,可以向脚本传递参数。脚本内获取参数的格式为:$n。n代表一个数字,1为执行脚本的第一个参数,2为执行脚本的第二个参数,以此类推…
$0 表示当前脚本名称。

1.修改helloworld.sh为

1 #!/bin/bash
2 echo $1
3 echo $2
4 echo $3

2.执行携带参数

1 [root@centos6-1 ~]# ./helloworld.sh haha wowow nini
2 haha
3 wowow
4 nini
5 [root@centos6-1 ~]#

五.位置参数变量

$n (功能描述:n 为数字,$0 代表命令本身,$1-$9 代表第一到第九个参数,十以上
的参数,十以上的参数需要用大括号包含,如${10})
$* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
$@ (功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)
$# (功能描述:这个变量代表命令行中所有参数的个数)
$? (功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明
上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则
证明上一个命令执行不正确了。)
$$ (功能描述:当前进程的进程号(PID))
$! (功能描述:后台运行的最后一个进程的进程号(PID))

a)$*和$@都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 $2 …$n
的形式输出所有参数
b)当它们被双引号“”包含时,“$*”会将所有的参数作为一个整体,以“$1 $2 …$n”的形
式输出所有参数;“$@”会将各个参数分开,以“$1” “$2”…”$n”的形式输出所有参数
[root@localhost shell]# cat position.sh
#!/bin/bash

echo "$1"
echo "$2"
echo "$*"
echo "$@"
echo "$#"
[root@localhost shell]# ./position.sh 10 20
10
20
10 20
10 20
2
[root@localhost shell]# cat position1.sh
#!/bin/bash

echo "$$"
./helloworld.sh &
echo "$!"
echo "$?"
[root@localhost shell]# ./position1.sh
1751
1752
0

 

六.Shell字符串

单引号字符串中不支持引用变量,任何字符都会原样输出,单引号会将所有特殊字符脱意
单引号字串中不能出现单引号(对单引号使用转义符后也不行)
双引号里可以引有变量,双引号里支持转义字符

1 [root@localhost shell]# name='my name is zaomianbao'; echo $name
2 my name is zaomianbao
3 [root@localhost shell]# name_again="\"${name}\""; echo $name_again   //经过转义
4 "my name is zaomianbao"
5 [root@localhost shell]# name_again="${name}"; echo $name_again      //不经过转义
6 my name is zaomianbao
7 [root@localhost shell]# echo ${#name}   //字符串长度
8 21

七.shell数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。在Shell中,用括号来表示数组,数组元素用“空格”符号分割开。定义数组的一般形式为:
        array_name=(value1 … valuen)

 1 //第一数组
 2 [root@centos6-1 ~]# usernames=(1 2 33 44 adsd1)
 3 //默认读取第一个
 4 [root@centos6-1 ~]# echo ${usernames}
 5 1
 6 //读取下标为0的
 7 [root@centos6-1 ~]# echo ${usernames[0]}
 8 1
 9 //读取下标为1的
10 [root@centos6-1 ~]# echo ${usernames[1]}
11 2
12 //读取所有
13 [root@centos6-1 ~]# echo ${usernames[*]}
14 1 2 33 44 adsd1
15 //同样是读取所有
16 [root@centos6-1 ~]# echo ${usernames[@]}
17 1 2 33 44 adsd1
18 //获取数组长度
19 [root@centos6-1 ~]# echo ${#usernames[@]}
20 5
21 //同样可以获取数组长度
22 [root@centos6-1 ~]# echo ${#usernames[*]}
23 5

八.shell运算符

Shell和其他编程语音一样,支持包括:算术、关系、布尔、字符串等运算符。
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。expr 是一款表达式计算工具,使用它能完成表达式的求值操作

基本语法:

(1)“$((运算式))”或“$[运算式]”    推荐
(2)expr m + n , 注意 expr 运算符间要有空格

1.算术运算符

+       加法
-        减法
*        乘法  
/        除法
%      模,即取余


Last login: Sun Mar 1 21:41:40 2020
[root@localhost ~]# a=10
[root@localhost ~]# b=20
[root@localhost ~]# var=$[$a+$b];echo $var
30
[root@localhost ~]# var=$[$a-$b]; echo $var
-10
[root@localhost ~]# var=$[$a * $b]; echo $var
200
[root@localhost ~]# var=$[$b / $a]; echo $var
2
[root@localhost ~]# var=$[$b % $a]; echo $var
0
[root@localhost ~]#


2.关系运算符

-eq   EQUAL等于
-ne   NOT EQUAL不等于
-gt   GREATER THAN大于
-lt   LESS THAN小于
-ge   GREATER THAN OR EQUAL 大于等于
-le   LESS THAN OR EQUAL 小于等

 1 #!/bin/bash
 2 
 3 a=10
 4 b=20
 5 
 6 if [ $a -eq $b ]
 7 then
 8    echo "$a -eq $b : a 等于 b"
 9 else
10    echo "$a -eq $b: a 不等于 b"
11 fi
12 if [ $a -ne $b ]
13 then
14    echo "$a -ne $b: a 不等于 b"
15 else
16    echo "$a -ne $b : a 等于 b"
17 fi
18 if [ $a -gt $b ]
19 then
20    echo "$a -gt $b: a 大于 b"
21 else
22    echo "$a -gt $b: a 不大于 b"
23 fi
24 if [ $a -lt $b ]
25 then
26    echo "$a -lt $b: a 小于 b"
27 else
28    echo "$a -lt $b: a 不小于 b"
29 fi
30 if [ $a -ge $b ]
31 then
32    echo "$a -ge $b: a 大于或等于 b"
33 else
34    echo "$a -ge $b: a 小于 b"
35 fi
36 if [ $a -le $b ]
37 then
38    echo "$a -le $b: a 小于或等于 b"
39 else
40    echo "$a -le $b: a 大于 b"
41 fi

执行

1 [root@centos6-1 ~]# ./helloworld.sh  
2 10 -eq 20: a 不等于 b
3 10 -ne 20: a 不等于 b
4 10 -gt 20: a 不大于 b
5 10 -lt 20: a 小于 b
6 10 -ge 20: a 小于 b
7 10 -le 20: a 小于或等于 b
8 [root@centos6-1 ~]# 

3.布尔运算符

&& 与
|| 或

 1 #!/bin/bash
 2 
 3 a=10
 4 b=20
 5 
 6 if [[ $a -lt 100 && $b -gt 100 ]]
 7 then
 8    echo "返回 true"
 9 else
10    echo "返回 false"
11 fi
12 
13 if [[ $a -lt 100 || $b -gt 100 ]]
14 then
15    echo "返回 true"
16 else
17    echo "返回 false"
18 fi

执行

1 [root@centos6-1 ~]# ./helloworld.sh 
2 返回 false
3 返回 true
4 [root@centos6-1 ~]# 

按照文件权限进行判断
-r 有读的权限
-w 有写的权限
-x 有执行的权限
按照文件类型进行判断
-f 文件存在并且是一个常规的文件
-e 文件存在
-d 文件存在并是一个目录

 

九.流程控制

1.if语法

if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi

注意事项:(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
 1 [root@localhost shell]# cat if.sh
 2 #!/bin/bash
 3 read -p "please input your name:"  NAME
 4 if [ $NAME == root ]
 5         then
 6                 echo "hello ${NAME},  welcome !"
 7         elif [ $NAME == tom ]
 8                 then
 9                         echo "hello ${NAME},  welcome !"
10         else
11                 echo "get out here !"
12 fi
13 [root@localhost shell]# ./if.sh
14 please input your name:tom
15 hello tom,  welcome !
16 [root@localhost shell]# ./if.sh
17 please input your name:dfdff
18 get out here !
19 [root@localhost shell]# 

2.case语法:

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

[root@localhost shell]# cat case.sh
#!/bin/bash
case $1 in
start)
        echo "starting"
        ;;
stop)
        echo "stoping"
        ;;
*)
        echo "Usage:{start|stop}"
esac
[root@localhost shell]# ./case.sh start
starting
[root@localhost shell]# ./case.sh stop
stoping
[root@localhost shell]# ./case.sh stopfdff
Usage:{start|stop}
[root@localhost shell]# 

取值后面必须为关键字 in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。;; 与其他语言中的 break 类似,意思是跳到整个 case 语句的最后。取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。

3.for语法

for (( 初始值;循环控制条件;变量变化 ))
do
程序
done

 1 [root@localhost shell]# cat for.sh
 2 #!/bin/bash
 3 
 4 sum=0
 5 for((i=1;i<=100;i++))
 6 do
 7         sum=$(($sum + $i))
 8 done
 9 echo 'sum='$sum
10 [root@localhost shell]# ./for.sh
11 sum=5050
12 [root@localhost shell]# 

4.while语法

while [ 条件判断式 ]
do
程序
done

注意事项:(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格


[root@localhost shell]# cat while.sh
#!/bin/bash

sum=0
i=1
while [ $i -le 100 ]
do
sum=$(($sum + $i))
i=$(($i + 1))
done
echo 'sum='$sum

[root@localhost shell]# ./while.sh
sum=5050

十.read读取控制台的输入

基本语法:
read(选项)(参数)
选项:-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)。
参数
变量:指定读取值的变量名

[root@localhost shell]# read -p "please input your name:" NAME
please input your name:LIUYI
[root@localhost shell]# echo $NAME
LIUYI

十一.系统函数

1)basename 基本语法
basename [pathname] [suffix]
basename [string] [suffix] (功能描述:basename 命令会删掉所有的前缀包括最后一
个(‘/’)字符,然后将字符串显示出来。
选项:
suffix 为后缀,如果 suffix 被指定了,basename 会将 pathname 或 string 中的 suffix 去掉。 案例

[root@localhost shell]# basename /root/shell/helloworld.sh
helloworld.sh
[root@localhost shell]# basename /root/shell/helloworld.sh .sh
helloworld

2)dirname 基本语法
dirname 文件绝对路径 (功能描述:从给定的包含绝对路径的文件名中去除文件名
(非目录的部分),然后返回剩下的路径(目录的部分)) 案例

[root@localhost shell]# dirname /root/shell/helloworld.sh
/root/shell

十二.函数

函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高。像其他编程语言一样,Shell 也支持函数。Shell 函数必须先定义后使用。

1 #!/bin/bash
2 
3 demoFun(){
4     echo "这是我的第一个 shell 函数!"
5 }
6 echo "-----函数开始执行-----"
7 demoFun 
8 echo "-----函数执行完毕-----"

执行

1 [root@centos6-1 ~]# ./helloworld.sh 
2 -----函数开始执行-----
3 这是我的第一个 shell 函数!
4 -----函数执行完毕-----
5 [root@centos6-1 ~]# 

 十三.awk分割用法(默认按空格分割,如果需要指定后面跟参数 -F)

[root@localhost shell]# df -h | awk '{print $1 "\t" $2 "\t" $3}'
Filesystem      Size    Used
devtmpfs        484M    0
tmpfs   496M    0
tmpfs   496M    6.8M
tmpfs   496M    0
/dev/mapper/centos-root 6.7G    5.1G
/dev/sda1       497M    157M
/dev/dm-3       10G     257M
tmpfs   100M    0
[root@localhost shell]# 
[root@localhost shell]# cat /etc/passwd | awk -F: '{print $1 "\t" $2 "\t" $3}' 
root    x       0
bin     x       1
daemon  x       2
adm     x       3

十四.定时 crontab -e

 

 十五.  追加错误日志

[root@localhost ~]# cat t2.sh
#!/bin/bash
pwd
pxxx
[root@localhost ~]# bash t2.sh >c.log 2>&1
[root@localhost ~]# cat c.log
/root
t2.sh: line 3: pxxx: command not found
[root@localhost ~]#
posted on 2020-02-29 17:34  从精通到陌生  阅读(253)  评论(0编辑  收藏  举报