shell脚本的基础入门 shell中$(( ))、$( )、``与${ }的区别

一.【shebang】 
二.【变量】 
三.【逻辑运算】 
四. 数值、字符串、文件测试、组合测试
五.【read命令】


【前言】

  脚本文件需要拥有执行权限,不然它只是一个普通文件。


一.【shebang】

首先,创建文件:vim filename,在文件的开头写一个命令:

这里写图片描述

这一行命令有一个统称,叫做”! shebang“ :

这里写图片描述

  由上可知,”shebang“写在Unix系统的脚本第一行,指明了执行这个脚本文件的解释程序。如果我们没有指定shebang或者系统中没有所指定的shebang时,会出现以下情况:

  1. 如果脚本文件中没有#!这一行,那么它执行时会默认Shell去解释这个脚本(即:$SHELL环境变量)。
  2. 如果#!指定的解释程序不是一个可执行文件,那么指定的解释程序会被忽略,转而交给当前默认的SHELL去执行这个脚本。
  3. 如果#!之后的解释程序是一个可执行文件,那么执行这个脚本时,它就会把文件名及其参数一起作为参数传给那个解释程序去执行。
  4. 如果#!指定的解释程序没有可执行权限,则会报错“bad interpreter: Permission denied”。
  5. 如果#!指定的解释程序不存在,那么会报错“bad interpreter: No such file or directory”。注意:#!之后的解释程序,需要写其绝对路径(如:#!/bin/bash),它是不会自动到$PATH中寻找解释器的。
  6. 当然,如果使用”bash test.sh ”这样的命令来执行脚本,那么#!这一行将会被忽略掉,解释器当然是用命令行中显式指定的bash。

er      二.【变量】

  在Linux中变量定义规则:

1、不能使程序中的保留字:例如if, for 
2、只能使用数字、字母及下划线,且不能以数字开头 
3、见名知义 
4、统一命名规则:驼峰命名法

  我们通过一个例子来简单说明一个变量:

这里写图片描述

  在bash中将变量分为几类:本地变量、环境变量、局部变量、位置变量、特殊变量。

      在shell中,进程有父进程和子进程,如何开一个子进程如下:

这里写图片描述

本地变量定义了一个变量,这个变量只在shell下显示,在子进程里不显示值。

 

环境变量:在变量前加export ,该变量可以在子shell下显示值。生效范围--当前shell进程及其子进程。

位置变量$1, $2, …来表示,用于让脚本在脚本代码中调用通过命令行传递的参数

参数 注释
$1, $2, … 对应第1、第2等参数,shift [n]换位置
$0 命令本身
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@ 传递给脚本的所有参数,每个参数为独立字符串
$# 传递给脚本的参数的个数(不包含$0)
$@ $*

只在被双引号包起来的时候才会有差异 

不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。

被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;

                                   "$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。

set – 清空所有位置变量

特殊变量

参数 注释
$0 命令本身
$? 上个命令的退出状态(或函数的返回值)
$$ 当前shell进程ID
$_ 查看上一个命令的最后一个变量。

 变量不仅可以赋值,还可以引用;

[root@localhost ~]# C1="root"      直接字符串引用
[root@localhost ~]# echo $C1
root
[root@localhost ~]# C1="$USER"     引用一个变量
[root@localhost ~]# echo $C1  
root
[root@localhost ~]# C1=`ls /app/`  引用一个命令的执行结果,注意引用符号    这里应该用双引号吧??
[root@localhost ~]# echo $C1     
bao.tar ceshi f1 file1 FILE1 fstab passwd profile.sh test.sh wan

单引号: 所见即所得:即将单引号内的内容原样输出,或者描述为单引号里面看见的是什么就会输出什么。

双引号: 把双引号内的内容输出出来;如果内容中有命令,变量等,会先把变量,命令解析出结果,然后在输出最终内容来。

             双引号内命令或变量的写法为`命令或变量`或$(命令或变量)。

 无引号:

     如果内容中有命令,变量等,会先把变量,命令解析结果,然后在输出最终内容来。

     如果字符串中带有空格等特殊字符,则视为一个整体,不能完整输出,需要改加双引号。

     一般连续的字符串,数字,路径等可以用,不过最好用双引号替代之

练习一:编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中

[root@localhost bin]# vim /root/bin/backup.sh
#!/bin/bash                  首行写"shebang"
# ------------------------------------------
# Filename: backup.sh
# Revision: 1.1
# Date: 2017/06/01           其余以#开头的行为注释行,为了使自己也使别人                                
# Author:wanwanperfect       更加快速的了解脚本的内容
# Description:
# ------------------------------------------
cp -a /etc /root/etc$(date +%F)             脚本需求
[root@localhost bin]# chmod u+x backup.sh   给脚本加上执行权限
[root@localhost bin]# ./backup.sh           执行这个脚本
[root@localhost bin]# cd /root/
[root@localhost ~]# ls
a.log   bin   Desktop   Downloads   file.grep   motd   new.file  Public     Videos  anaconda-ks.cfg  b.log  Documents  etc2017-08-10  initial-setup-ks.cfg  Music  Pictures  Templates                   创建成功

shell中变量没有类型:根据表达式自动改变其类型!

表达式不能计算结果:变成了字符串的拼接!

算数运算:可以计算结果

在bash中,定义一个变量的值也可以使用算数运算,主要有以下几种方式:

(1) let var=算术表达式

(2) var=$[算术表达式]

(3) var=$((算术表达式))

(4) var=$(expr arg1 arg2 arg3 …) 乘法时要转译* ,即*

(5) declare –i var = 数值

(6) echo ‘算术表达式’ | bc (丢给计算机进行处理)

[root@localhost ~]# let a=2+3
[root@localhost ~]# echo $a
5
[root@localhost ~]# b=$[20*12]
[root@localhost ~]# echo $b
240
[root@localhost ~]# c=$((3+3))  
[root@localhost ~]# echo $c
6
[root@localhost ~]# d=$(expr 4 \* 5 + 3)
[root@localhost ~]# echo $d
23
[root@localhost ~]# declare -i n=8
[root@localhost ~]# echo $n
8
[root@localhost ~]# echo 4*4 |bc
16
  • 另外除了一些算数运算,变量还有自增赋值自减赋值

let var+=1 <表示自加1 后赋值>

let var++

let var-=1 <表示自减1 后赋值>

let var–

联系shell脚本2. 编写脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和

#!/bin/bash
#------------------------------------------------------
#Filename:sumspace47.sh                                 
#Revision:                                            
#Date:2017-08-02                                                
#Author:wanwanperfect                                                                              
#------------------------------------------------------
file1=$(cat $1 |grep -o "^[[:space:]]*$"|wc -l)  定义$1$2作为参数 [:space:] 空白字符,包括空格,tab [空格 tab]
file2=$(cat $2|grep -o "^[[:space:]]*$"|wc -l)   grep -o  只显示匹配的部分。wc -l计内容行数
echo "空行之和为:"$[file1+file2]""          使用算数运算来达到目的
unset file1 file2                          别忘记使用unset命令来释放变量,不然会占取你的内存呦~

shell中$(( ))、$( )、``与${ }的区别

https://blog.csdn.net/jiaxiaokai/article/details/80870269

 三.【逻辑运算】

在逻辑运算中,我们只定义两个值,即 true 和 false ,分别用 1 和 0 表示。

逻辑运算分为三种:

与:只要有一个假则为假        1 与 1 = 1     1 与 0 = 0       0 与 1 = 0       0 与 0 = 0

或:只要有一个真则为真        1 或 1 = 1        1 或 0 = 1      0 或 1 = 1        0 或 0 = 0

非:!       ! 1 = 0           ! 0 = 1

短路与:前一个为假,则不再判断第二个值。 用 && 表示

短路或:前一个为真,则不再判断第二个值。 用 || 表示。

异或:异或的两个值,相同为假,不同为真 。 用 ^ 表示。

前两个符号我们常用于脚本中来判断一些条件的成立与否。

这里写图片描述 】~~~~~~~~~~

[root@localhost bin]# id root &> /dev/null && echo "user is exist" || echo "user is not exist"  
user is exist            当返回结果为真时则执行&& 后的命令
[root@localhost bin]# id xiaoqiang &> /dev/null && echo "user is exist" || echo "user is not exist"    
user is not exist     当返回结果为假时则执行||后的命令

【test命令】

 test命令用来检测两个字符或者比较两个值的大小来返回&& 或者||的值。

 其实,test 命令可以用 ”[“ 来表示,”[“命令还有一个参数为”]“ 。注意:它们一个是命令,一个是该命令的参数,并不是合体的~~ ”[ ]“ 表示将参数放入其中进行比较,与test 命令用法相同。例如:

[root@localhost bin]# a=aaa
[root@localhost bin]# b=aa
[root@localhost bin]# test "$a" == "$b" && echo true || echo false
false
[root@localhost bin]# [ "$a" == "$b" ] && echo true || echo false 
false

【注意】在使用”[]” 左右大括号旁边必须有空格间隔。

 四. 数值、字符串、文件测试、组合测试

数值测试:

参数 注释
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等

 字符串测试:

参数 注释
== 是否等于
> ASCII码是否大于ASCII码
< 是否小于
!= 是否不等于
=~ 左侧字符串是否能够被右侧所匹配【此表达式一般用于[[ ]]中;支持扩展的正则表达式】
-z 字符串是否为空,空为真,不空为假
-n 字符串是否不空,不空为真,空为假

文件测试:

参数 注释
-a FILE 文件存在性测试,存在为真,否则为假
-e FILE 同-a
-b FILE 判断文件为块设备文件时为真
-c FILE 判断文件为字符设备文件时为真
-d FILE 判断文件为目录文件时为真
-f FILE 判断文件为普通文件时为真
-h FILE 或 -L FILE 判断文件为符号链接文件时为真
-p FILE 判断文件为命名管道文件时为真
-S FILE 判断文件为套接字文件时为真
-r FILE 判断文件存在且可读时为真
-w FILE 判断文件存在且可写时为真
-x FILE 判断文件存在且可执行权限时为真
-u FILE 判断文件且拥有suid权限时为真
-g FILE 判断文件存在且拥有sgid权限时为真
-k FILE 判断文件且拥有sticky权限时为真
-s FILE 是否存在且非空时为真
-t fd fd表示文件描述符是否已经打开且与某终端相关
-N FILE 文件自动上一次被读取之后是否被修改过
-O FILE 当前有效用户是否为文件属主
-G FILE 当前有效用户是否为文件属组

                      
这里写图片描述~~~~~~~~~

[root@localhost bin]# b1=34
[root@localhost bin]# b2=12
[root@localhost bin]# [ $b1 -gt $b2 ] && echo true || echo false
true
[root@localhost bin]# [ $b1 -lt $b2 ] && echo true || echo false 
false
[root@localhost bin]# [ $b1 -eq $b2 ] && echo true || echo false  
false

练习:

编写脚本/root/bin/checkdisk.sh,检查磁盘分区空间和inode使用率,如果超过80%,就发广播警告空间将满

#!/bin/bash
var1=`df|egrep -o "[[:digit:]]{1,3}\b%"|cut -d '%' -f1|sort -nr|head -1`
var2=`df -i|egrep -o "[[:digit:]]{1,3}\b%"|cut -d '%' -f1|sort -nr|head -1`
[ $var1 -gt 80 ]&& wall warn:空间将满 ||wall 空间使用率不足80%
[ $var2 -gt 80 ]&& wall warn:inode空间将满 ||wall indoe空间使用率不足80%
unset var1 var2

【解题】将磁盘利用率和inode使用率的数字提取出来再与 80 进行比较就好了。


【bash 的组合测试条件】

(1)

命令1 && 命令2 表示并且

命令1 || 命令2 表示或者

! command 表示非

如:[[ -r file ]] && [[ -w file ]]

(2)

EXPRESSION1 -a EXPRESSION2 并且

EXPRESSION1 -o EXPRESSION2 或者

! EXPRESSION

必须使用测试命令进行

eg:[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

练练手:

  编写脚本/root/bin/excute.sh ,判断参数文件是否为sh后缀的普通文件,如果是,添加所有人可执行权限,否则提示用户非脚本文件;

#!/bin/bash
#------------------------------------------------------
#Filename:excute.sh                                   
#Author:wan                                           
#Date:2017-08-04                                                               
#Description:判断文件是否为脚本文件                                         
#-----------------------------------------------------
[ -f $1 ] && \
(varsh=`basename $1 |grep -o "\..*$"`
[[ "$varsh" == .sh ]] && [[ -f $1 ]] && (chmod u+x $1 && echo 该文件为脚本文件并且已添加可执行权限) || echo "该文件非脚本文件" )|| echo "该文件不存在"
unset varsh

  【解题】首先判断这个文件是不是以 .sh 结尾的文件,然后判断是不是一个普通文件。

这两个条件都满足时,判断这个文件是否存在,存在则给这个文件加上执行权限并输出正确结果,不满足其上任何一个条件则返回一个错误结果。


 五.【read命令】

  

与用户交互,提示用户需要输入的内容。把输入值分配给一个或多个shell变量。参数如下:

参数 注释
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n # 指定输入的字符长度最大值#
-d ‘字符’ 输入结束符,当你输入的内容出现这个字符时,立即结束输入
-t N 超出N秒没有进行输入,则自动退出。

【Ps】read 从标准输入中读取值,给每个单词分配一个变量,其余剩余的单词都被分配给最后一个变量。

[root@localhost ~]# read -p "请输入用户名 :" username && echo "您的用户名为$username"  
请输入用户名 :tom
您的用户名为 tom
[root@localhost ~]# read -sp "请输入密码 :" passwd && echo "您的密码为:$passwd "
请输入密码 :您的密码为:123456

猜你喜欢

转载自blog.csdn.net/jiaxiaokai/article/details/80833175