shell学习之路

目录

一.什么是shell

二.bash的注意事项

三.vi/vim

3.1在 /etc/vimrc中修改配置文件,永久生效

3.2 临时生效在进入文件后输入:set number 和1效果相同,但是是临时

3.3最终的效果

四.热身脚本(先跟着敲,踏出第一步)

4.1清除日志1.0版本

4.2清除日志2.0版本

4.3清除日志3.0版本

五.进入学习脚本的一步,学习注释符

5.1“#”

5.2“;”命令分隔符 ,在同一行上写两个或者多个命令

5.3句号 .

5.4引号: “” 部分引用  ‘’全引用

5.5逗号 用于连接多个算术操作,并返回最后一项

5.6斜线

5.7反引号

5.8冒号colon,空命令null command

5.9感叹号

5.10 星* asterisk

5.11问号 ? question mark

5.12美元符号$

5.13圆括号()parentheis

5.14大括号,花括号 brace

5.15 方括号,中括号 bracket [ ]

5.16 大于号与小于号 > &> >& >> < <>

5.17竖线

5.18 & 后台运行命令 Run job in background

5.19 - 减号Minus 连字符Hyphen、破折号Dash

5.20 等号= Equal

5.21 加号+ plus

5.22 %百分号 percen

5.23 ~ 波浪号 Tilde

5.24 ^ 脱字号,补字号 caret


一.什么是shell

什么是shell呢?shell是用C语言编写的程序,它是用户使用 Linux 的桥梁。Shell既是一种命令语言,又是一种程序设计语言。简单来说Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。也可以这样认为,linux中的shell就是linux内核的一个外层保护工具,并负责完成用户与内核之间的交互

二.bash的注意事项

1.shell命名:shell脚本名称一般为英文,大写,小写,后缀以.sh结尾

2.不能使用特殊符号、空格

3.shell编程,首行必须以 #!/bin/bash

4.SHELL脚本变量,不能以数字,特殊符号开头,可以使用下划线,但是不能使用破折号

三.vi/vim

Linux是一个万物文件的一个操作系统,在这里介绍一下vim/vi,基本上分为三种模式一般命令模式,编辑模式与命令模式。

对于初学者来说最好是添加行号,这有两种方法

3.1在 /etc/vimrc中修改配置文件,永久生效

vim /etc/vimrc  #修改配置文件,永久生效
set number  #在配置文件的最后一行添加

3.2 临时生效在进入文件后输入:set number 和1效果相同,但是是临时

3.3最终的效果

四.热身脚本(先跟着敲,踏出第一步)

4.1清除日志1.0版本

  1 #!/bin/bash
  2 #清除日志
  3 #要以root身份运行
  4 cd /var/log
  5 cat /dev/null > messags
  6 cat /dev/null > wtmp
  7 echo "Logs cleaned up."

4.2清除日志2.0版本

  1 #!/bin/bash
  2 #清除日志
  3 #要以root身份运行,如果不是root,会自定义的错误提示,然后退出
  4 # 使用变量,这样更加灵活,优雅
  5 LOG_DIR=/var/log
  6 cd $LOG_DIR
  7 cat /dev/null > messags
  8 cat /dev/null > wtmp
  9 echo "Logs cleaned up."
 10 exit #这个命令是正确,合适的退出的办法
 11      #不带任何参数的exi,将返回退出的状态码

4.3清除日志3.0版本

 1 #!/bin/bash
  2 # 清除日志
  3 # 要以root运行,如果不是root,会自定义的错误提示,然后退出
  4 #如果使用变量,这样更加灵活,优雅
  5 LOG_DIR=/var/log
  6 ROOT_UID=0  # $UID为0,用户为root权限
  7 LINET=50   # 默认的保存的行数
  8 E_XCD=66   # 退出代码:表示不能修改目录位置
  9 E_NOROOT=67 #退出代码:表示不是root用户
 10  # 以root身份来运行这个脚本
 11 if  [ "$UID" -ne "$ROOT_UID" ]
 12 then
 13   echo " Must be root run this script."
 14   exit $E_NOROOT
 15 fi
 16 # 测试是否给这个脚本传递有参数(非空)
 17 if [ -n "$1" ]
 18 then
 19   lines=$1
 20 else
 21   lines=$LINES #如果没有在命令指定,就使用默认值
 22 fi
 23 cd $LOG_DIR
 24 #如果处理log file 之前,应当确定当前目录是否正确
 25 #如果不在/var/log目录中
 26 if [ `pwd` != "$LOG_DIR"  ]  # 或 if [ "pwd" !="$LOG_DIR" ]
 27 then
 28   echo "Can't change $LOG_DIR"
 29   exit $E_XCD
 30 fi
 31 #保留mssage文件中的最后部分,而不是全部清除
 32 tail -$lines messages > mesg.tmp
 33 mv mesg.tmp messages
 34 # 旧的办法,不在需要了,新的办法更加安全吗?
 35 # cat /dev/null > messages
 36 cat /dev/null > wtmp
 37 echo "Logs cleaned up."
 38 exit 0
 39 #退出时返回0,0表成功
                                  

 脚本敲完了之后,热身就结束了,学习脚本,要边敲边理解,一定一定一定要手敲

五.进入学习脚本的一步,学习注释符

5.1“#”

  1 #!/bin/bash
  2 # This is a comment.
  3 echo "A comment will follow " # 注释在这里
  4 # 注意上一条语句中,#号前面要有一个空格
  5 # A tab precede this comment
  6 # 注意上一条语句中,注释是放在本行 行首空白的后面
  7 # echo中被引号的#,是不能被当作的注释的
  8 # echo中被转义的#,是不能被当作的注释的
  9 #反斜线是转义字符
 10 echo "111-双引号 The # here does not begin a comment."
 11 echo "222_单引号 The # here does not begin a comment."
 12 echo 333_无引导且有转义 The \# here does not begin a comment.
 13 echo 444_无引导无转义 The # here begin a comment.
 14 # 在特定的参数替换结构中,#号不是注释
 15 echo ${PATH#*:} #效果:将第一个冒号之前的删除
 16 # 在数字常量表达式中,#号不是注释
 17 echo $((2#101011)) # 数制转换,2进制转换为10进制,这不是注释

5.2“;”命令分隔符 ,在同一行上写两个或者多个命令

  1 #!/bin/bash
  2 #分号(separator [semicolon])测试
  3 echo hello ; echo there
  4 filename="ftt.txt"
  5 if [ -e "filename " ] ; then #注意:if 和 then 需要分离
  6   echo "File $filename exists." ; cp $filename $filename.bak
  7 else
  8   echo "File $filename not found." ; touch $filename
  9 fi ; echo "File test complete"

双分号,是case代码块的结束

case word in

模式1)

   命令序列;;

模式2)

  命令序列;;

........... *)

  命令序列n;;

esac

case语句支持多个条件的匹配,语法格式如下:

case word in

模式1|模式2|模式3)

命令序列1;;

模式4|模式5|模式6)

   命令序列2;;

... ... *)  

   命令序列n;;

esac

功能描述:使用case进行字母比较

在括号前面的内容与后面的命令序列之间,可以使用回车键换行,也可以没有换行

请输入一个a~c之间的字母

使用;&会执行后一个模式匹配中的命令

使用;;&会继续对后面的模式进行匹配

所以屏幕会继续显示后面的字母

  1 #!/bin/bash
  2 #双分号
  3 variable='abc'
  4 case "$variable" in
  5 adc)
  6   echo "\$variable = abc";;
  7 sxz)
  8   echo "\$variable = sxz";;
  9 esac
 10 exit

5.3句号 .

 [root@server1 ~]# vim ftt.txt

f=sxzftt

x=fttsxz

t=123456

  1 #!/bin/bash
  2 #点命令测试,点命令与source命令效果相同
  3 . ftt.txt #加载一个数据文件
  4 # 这与source ftt.txt 效果相同
  5 #ftt.txt必须存在于当前目录
  6 #下面,引用数据文件中定义的一个变量
  7 echo f
  8 exit

5.4引号: “” 部分引用  ‘’全引用

[root@server1 ~]# echo $PWD

/root

[root@server1 ~]# echo "$PWD"

/root

[root@server1 ~]# echo '$PWD'

$PWD

  1 #!/bin/bash
  2 #引号练习 + 变量赋值练习
  3 a=ftt
  4 s=$a
  5 #------------------------------------------------------------
  6 #强烈注意:赋值时,等号前后一定要不要有空格
  7 #1,如果等号前面有空格?
  8 #VARIABLE =value
  9 #将执行带一个参数=value的命令 VARIABLE
 10 #如果等号后面有空格?
 11 # VARIADLE= value
 12 #将执行后面这个小写的value命令,并且一个赋值为“”的变量VARIADLE
 13 #-------------------------------------------------------------
 14 echo s # 这不是一个变量,所以只会输出s
 15 echo $s
 16 echo "$s" #结果同上一行
 17 echo "$s"
 18 echo '$s'
 19 echo 
 20 exit

5.5逗号 用于连接多个算术操作,并返回最后一项

[root@server1 ~]# let "t1 = ((a = 9,15/3))"

[root@server1 ~]# echo "tl = $t1"

tl = 5

[root@server1 ~]# let "t1 = ((a = 5+3,7-1,15-3))"

[root@server1 ~]# echo "t1=$t1"

t1=12

[root@server1 ~]# let "t3=((a=9,15/3))"

[root@server1 ~]# echo "t3=$t3 a=$a"

t3=5 a=9

5.6斜线

\反斜线 backslash 转义符

  \n

新的一行

 \r

回车

 \t

水平制表符

\v

垂直制表符

\b

后退符

\a

“alert” (蜂鸣或者闪烁)

\0xx

转换为八进制的ASCLL码,等价于0xx

/正斜线 forward slash

文件名路径分隔符 例:/etc/yum.repos.d

除法算法操作符

5.7反引号

返引号 back quote,命令替换

  1 #!/bin/bash
  2 #本脚本的名称为:fan.sh
  3 #用于测试反引号back quote的命令替换commnad substitution功能
  4 
  5 echo $0
  6 script_name=`basename $0`
  7 echo script_name
  8 
  9 script_name=`basename -s .sh $0`
 10 echo script_name
 11 exit

5.8冒号colon,空命令null command

  1 #!/bin/bash
  2 #实例代码:冒号colon,空命令 null command
  3 # 例1 死循环
  4 #while : #本行等同于 while true
  5 #do
  6   #echo word
  7 #done
  8 # 例2 : #if/then的占位符 placeholder
  9 if condition
 10 then : #什么都不做,引出分支,有可能以后补充
 11 else    
 12    take-some-action
 13 fi      
 14 #例3:清空一个文件,但不会修改该文件的权限,也cat /dev/null类似
 15 #     由于空命令是一个内建的命令,所以不会生产一个新进程
 16 : >> ftt.txt

5.9感叹号

!取反操作符reverse

反转命令的退出状态码

反转测试操作符的意义

正确的代码千遍一律,错误的代码千奇百怪

例如:

[root@server1 ~]# cd
[root@server1 ~]# echo $? 正确且运行成功的查看为0
0
[root@server1 ~]# cdd
-bash: cdd: 未找到命令
[root@server1 ~]# echo $? 错误的就千奇百怪了
127

  1 #!/bin/bash
  2 # 叹号!取反操作符 与退出状态码的练习
  3 # ture 与冒号都是什么不做的命令
  4 true
  5 echo "Exit status of \"true\" =$?"
  6 ! true #注意感叹号!与命令之间空格
  7 echo "Exit status of \"true\" =$?"
  8 #退出状态码必须是十进制数,范围是0-255
  9 exit 88

5.10 星* asterisk

1.文件名通配符 wild card、globbing

[root@server1 ~]# ls -l * 相当于ll *在里面的作用是查找所有文件

[root@server1 ~]# ls -l [ab]*  查找开头为a和b的所有文件

[root@server1 ~]# ls -l [a-c]*   查找开头为a到c的所有文件

[root@server1 ~]# ls -l [^ab]*  查找除了a和b之外的所有文件

[root@server1 ~]# ls -l {b*,c*,*est*}  查找文b和以及文件中带有est的所有文件

在这补充一个额外的千万千万不要尝试,俗称删库跑路

[root@server1 ~]# rm -rf /*

2.正则表达哦式,metacharacter、regular expression

  匹配任意个数(包含0个)的字符

  例:1133*    匹配11加一个或多个三

3.乘法  multiplication

  ** 幂 exponentiation

5.11问号 ? question mark

 1.文件名通配符 wild card、globbing

     [root@server1 ~]# ls -l t?.sh 匹配单个字符,t1,t1……

2.正则表达式,metacharacter、regular expression

     匹配它前面的字符,1次或0次。通常用来匹配单个字符

3.测试操作符test operator

(1).在双圆括号结构表达式中,用来测试一个条件的结果(三元操作符 三个条件if-then-else)

      {((…))双圆括号结构

       a.于let命令很相似,允许算术扩展和赋值

       [root@server1 ~]# a=$((5+3))

       [root@server1 ~]# echo $a

       8

       b.在bash中,使用C语言风格变量操作的一种处理机制

      (( a= 23))  # 变量赋值,“=”两边允许有空值

    (( a++ ))    #后置自加

    (( a--  ))    #后置自减

    (( ++a ))   #前置自加

    (( --a  ))   #前置自减  }

      [root@server1 ~]# (( var0 = var1<98?9:21))                                                                                     var这个变量如果下于98那就把9赋值给var0,否者就是21

       [root@server1 ~]# echo $var0

      9

  1 if [ "$var0" -lt 98 ] #-lt less then 小于
  2 then
  3   var1=9
  4 else
  5   var1=21
  6 fi

    这个两种输出结果一样,但是三元的代码量减少不少

(2).在参数替代表达式中,用来测试一个变量是否被设置

      $ {} 参数替代(方法的其中之一) parameter substitution

     如果变量未被声明或赋值,那么就输出错误信息(错误信息是可以指定的)

    $ {parameter?err_msg}   如果变量未声名

   $ {parameter:?err_msg}  如果变量声明了,但未赋值……

     a.正常地进行变量定义与赋值

       [root@server1 ~]# var1=123  

       [root@server1 ~]# echo $var1

       123

       [root@server1 ~]# echo ${var1}

       123

     b.变量未定义   

     [root@server1 ~]# echo ${var2}

                                                                                    

     [root@server1 ~]# echo ${var2?err_msg}  (错误信息指定的是err——msg)

     -bash: var2: err_msg   

     [root@server1 ~]# echo ${var2:?err_msg}

    -bash: var2: err_msg

    c.进定义了变量,但未赋值

    [root@server1 ~]# var3=

    [root@server1 ~]# echo ${var3}

    

    [root@server1 ~]# echo ${var3:?ll}

   -bash: var3: ll

如果一个环境变量或自定义变量没有被定义……

  1. 问题 :#正常地进行变量定义与赋值

        [root@server1 ~]# ORA_HOME=""

        [root@server1 ~]# if [ $ORA_HOME="" ] ; then echo "111" ; fi

        111

     2.问题:如果如果没有定义变量

       [root@server1 ~]# if [ $ORA_HOME="" ] ; then echo "111" ; fi

       111

  这两个都没有特别直观的查看一个变量是否被赋值

 解决方法:

   使用问号 ?来测试一个变量是否被设置

   如果没有被设置,就输出一个错误退出脚本

   这个错误可以自定义

  

 1 #!/bin/bash
  2 #使用参数替换和错误信息
  3 #例1:检查一些系统环境变量,这是一个预防性保护的好习惯
  4 #   例如:如果$USER没有被设置,系统将无法识别你
  5 : ${HOSTNAME?} ${USER?} ${HOME?} ${MALL}
  6 #向NULL命令传递四个测试
  7 echo
  8 echo "Name of then machine is $HOSTNAME"
  9 echo "You are "$USER""
 10 echo "Your home directory is $HOME"
 11 echo "Your mail INBOX is located in $MALL"
 12 echo 
 13 echo "If you are reading this messags"
 14 echo "critical environmental vatiables have benn set"
 15 echo
 16 echo
 17 #例2:#[variable?] 结构也能检查脚本中变量的设置情况
 18 ThisVariable=Value-of-ThisVariable
 19 : "Variable of ThisVaiable is $ThisVariable"
 20 echo
 21 echo
 22 : ${SF?"SF ha not been set."}
 23 #如果SF没有被设置的话,那么这个脚本会打印一个错误消息,然后退出
 24 #你可以自己指定错误消息
 25 # : ${variablenaem?"ERROR MESSAGE"}
 26 #和上面的测试方法一样于下面的效果相同
 27 #  dummy_variable=${sxz}
 28 #  dummy_variable=${sxz?"sxz has not been set."}
 29 #  echo ${sxz} > /dev/null
 30 #bash的设置值 set -u 可以强制检查变量是否被设置的方法
 31 echo "You will not sess this message,because script already terminated."
 32 
 33 HERE=0
 34 exit $HERE不会在这里面退出
 35 #事实上,这个脚本将会返回值1作为退出状态($echo $?)

 

 默认情况下bash是检查variable是否被使用

 例[root@server1 ~]# echo $ll

 [root@server1 ~]# echo $cc

                                                    这个是不报错的

 [root@server1 ~]# set -u   打开bash检查variable是否使用

 [root@server1 ~]# echo $cc

 -bash: cc: 为绑定变量

 [root@server1 ~]# set +u  关闭

 [root@server1 ~]# echo $c

5.12美元符号$

$的用途

1.$ 变量替换(引用的内容) Variable  substitution

 1.1  变量的名字就是变量保存值的地方

 1.2  引用变量的值就叫做变量替换

 [root@server1 ~]# variable=123

 [root@server1 ~]# echo variable

 variable

 [root@server1 ~]# echo $variable

 123

 [root@server1 ~]# echo ${variable}

 123

1.3  在一些情况下,变量没有前缀名$

  1.3.1变量被声明或赋值

  1.3.2 变量被unset

  1.3.3 变量被export

  1.3.4 变量代表一种信号(发给进程的一个简单消息,目的是:通知目的进程采取一系列的指令动作)

1.4 在引用时,$的变化

  1.4.1 单引号(‘ ’),强引用,保持字面意思

  1.4.2 双引号(“ ”),弱引用,发生变量替换

2.$ 正则表达式中的行结束符   Regular expression

  在RE中用来匹配行尾,例:

     “abc$” 匹配行尾的abc

      “^$”  匹配空行
3.$ { } 参数替代  Parameter substitution

3.1如果变量未被声明或赋值,那么就输出错误信息(错误信息是可以指定的)

   $ {parameter?err_msg}   如果变量未声名

  $ {parameter :? err_msg}  如果变量声明了,但未赋值……

3.2如果变量未被声明或赋值,那么就替换为默认值

  ${ parameter-default } 是否被声明,如果没有就指定为默认值

  ${ parameter:-default } 是否被赋值,如果没有就把default指定为变量

  1 #!/bin/bash
  2 #variable.sh
  3 # 一个变量是否被声明或设置,将会影响变量是否使用默认值
  4 # 情况1:没有声明,直接使用
  5 echo "username1 has not declared."
  6 echo "Test1A: username1 = ${username1-`whoami`}" #有输出
  7 echo "Test1A: username1 = ${username1:-`whoami`}" #有输出
  8 echo
  9 #情况2:声明了变量,但变量值为空null
 10 username2=
 11 echo "username2 has been declared,but is set ton null."
 12 echo "Test2B: username2 = ${username2-`whoami`}" #无输出
 13 echo "Test2B: username2 = ${username2:-`whoami`}" #有输出
 14 #有输出,因为:-会比-多了一个测试条件

 

4.$ ‘ … ‘ 引用字符串扩展  Ouoted string expansion bash 默认时十进制

  [root@server1 ~]# quote=$'\042'   42八进制 转义到字符为“

  [root@server1 ~]# echo $quote

  "

5.$#,$*,$@位置参数   pcsitional parameters

  5.1 $0,$1,$2,等的

     位置参数,从命令行传递到脚本,或者传递给函数

  5.2$#

      命令行参数或者位置参数的个数

  5.3$*

     所有的位置参数都被看作一个单词

  5.4$@

     与$*相同,但是每个参数都是一个独立的引用字符串

6.$?退出状态码变量   Exit status variable

7.$ 进程ID变量       process ID variable

5.13圆括号()parentheis

1.命令组

  [root@server1 ~]# a=123  父进程

  [root@server1 ~]# (echo "a = $a"; a=321; echo "a = $a")   子进程 

  a = 123

  a = 321

 [root@server1 ~]# echo "a = $a" 只能读取父进程

 a = 123

 2.数组初始化

 Array=(element1 element2 elemet2)

5.14大括号,花括号 brace

1.扩展  expansion

  1 #!/bin/bash
  2 #把file1,file2,file3连接在一起,并且定向到combined_file中
  3 cat {file1,file2,file3} > combined_file
  4 #拷贝“file1.txt”到“file1.bakkup” 中
  5 cp file1.{txt,bakkup}
  6 #输出26个英文字母,阿拉伯数字
  7 echo {a..z} {0...11}

 2.代码块 Block of code 

  2.1变称为inline group,相当于创建了一个匿名函数(没有名字的函数)

  2.2 与“标准” 函数不同,在其声明的变量,对于脚本其他部分的来说是可见的

  1 #!/bin/bash
  2 #大括号代码块 和 IO重定向
  3 #从/etc/fstab中读行
  4 File=/etc/fstab
  5 {
  6 read line1
  7 read line2
  8 } < $File
  9 echo "First line if $File is:"
 10 echo "$line1"
 11 echo
 12 echo "First line if $File is:"
 13 echo "$line2"
 14 exit 0

 

安装rpm脚本

  1 #!/bin/bash
  2 #6-1rpm.sh
  3 #获得一个rpm文件的描述,文件列表,将检查是否已经安装
  4 #并将结果保存到一个文件中
  5 #此脚本通过一个代码块来实现
  6 SUCCESS=0
  7 E_NOARGS=65
  8 #判断是否给此脚本传递参数
  9 if [ -z "$1" ]
 10 then
 11   echo "Usage: `basename S0` rpm-file "
 12   exit $E_NOARGS
 13 fi
 14 {
 15  echo
 16  echo "Archive Description:"
 17  rpm -qpi $1 #rpm文件的描述
 18  echo
 19  echo "Archive Listing:"
 20  rpm -qpl $1 #rpm中文件列表
 21  echo
 22  rpm -i --test $1 #检查rpm包是否可以安装
 23  if [ "$?" -eq $SUCCESS ]
 24  then
 25    echo "$1 can be installed."
 26  else
 27    echo "$1 cannot be installed."
 28  fi
 29  echo 
 30 } > "$1.text" #将代码块的所有输出重定向到文件中
 31 echo "Results of rpm test in file $1.test"
 32 exit 0

 [root@server1 ~]# ./6-1rpm.sh origin-pod-3.7.1-2.el7.x86_64.rpm 

 [root@server1 ~]# more origin-pod-3.7.1-2.el7.x86_64.rpm

 安装rpm2.0判断rpm是否存在如果没有就直接退出

 1 #!/bin/bash
  2 #6-1rpm.sh
  3 #获得一个rpm文件的描述,文件列表,将检查是否已经安装
  4 #并将结果保存到一个文件中
  5 #此脚本通过一个代码块来实现
  6 SUCCESS=0
  7 E_NOARGS=65
  8 E_NOFILE=66
  9 #判断是否给此脚本传递参数
 10 if [ -z "$1" ]
 11 then
 12   echo "Usage: `basename S0` rpm-file "
  1 #!/bin/bash
  2 #6-1rpm.sh
  3 #获得一个rpm文件的描述,文件列表,将检查是否已经安装
  4 #并将结果保存到一个文件中
  5 #此脚本通过一个代码块来实现
  6 SUCCESS=0
  7 E_NOARGS=65
  8 E_NOFILE=66
  9 #判断是否给此脚本传递参数
 10 if [ -z "$1" ]
 11 then
 12   echo "Usage: `basename S0` rpm-file "
 13   exit $E_NOARGS
 14 fi
 15 #判断文件是否存在
 16 if [ ! -f "$!"]
 17 then
 18   echo "$1 not exist"
 19   exit $E_NOFILE
 20 fi
 21 {
 22  echo
 23  echo "Archive Description:"
 24  rpm -qpi $1 #rpm文件的描述
 25  echo
 26  echo "Archive Listing:"
 27  rpm -qpl $1 #rpm中文件列表
 28  echo
 29  rpm -i --test $1 #检查rpm包是否可以安装
 30  if [ "$?" -eq $SUCCESS ]
 31  then
 32    echo "$1 can be installed."
 33  else
 34    echo "$1 cannot be installed."
 35  fi
 36  echo 
 37 } > "$1.text" #将代码块的所有输出重定向到文件中
 38 echo "Results of rpm test in file $1.test"
 39 exit 0
 40 
                                                       

 vim -d 文件1 文件2 对比文件的不同

3.{}\;路径名 pathname

 [root@server1 ~]# find . -name "*.cfg"

 ./anaconda-ks.cfg

 [root@server1 ~]# find . -name "*.cfg" -exec cp {} /tmp \;

 [root@server1 ~]# ls /tmp/*.cfg

 /tmp/anaconda-ks.cfg

5.15 方括号,中括号 bracket [ ]

1.条件测试 Test

  1 #!/bin/bash
  2 echo "Testing \"0\""
  3 if [ 0 ] # zero
  4 then
  5   echo "0 is true."
  6 else         #Or else ...
  7   echo "0 is false."
  8 fi        # 0 is true.

 2.扩展测试[[ ]] test

  1 #!/bin/bash
  2 file=/etc/passwd
  3 if [[ -e $file ]] #exist
  4 then
  5   echo "Password file exists."
  6 fi

 

 3.数组元素 Array element

[root@server1 ~]# Array[1]=slot_1

[root@server1 ~]# echo ${Array[1]}

slot_1

4.字符范围 Range of characters

[syz]     匹配字符s,x或z

[c-n]     匹配字符c到字符n之间的任意一个字符

[B-Pk-y]  匹配从B到P,或者从k到之间的任意一个字符

[a-z0-9]  匹配任意小写字母或数字

[^b-d]   将会匹配范围在b到d之外的任意一个字符

[Yy] [Ee] [Ss]  能够匹配yes,Yes,YES,yEs,等等

[0-9] [0-9] [0-9]-[0-9]-[0-9]-[0-9] [0-9] [0-9] [0-9] 匹配美国的社保码

5.16 大于号与小于号 > &> >& >> < <>

1.重定向 redirection

重定向操作符

功能

< 文件名

重定向输入

>文件名

重定向输出

>> 文件名

追加输出

2> 文件名

重定向标准错误输出

2>> 文件名

重定向和追加标准错误输出

&>> 文件名

重定向标准输出和标准错误输出(首选方式*)

>& 文件名

重定向标准输出和标准错误输出

2>&1

将标准错误输出重定向到标准输出的去处

1>&2

将输出重定向到标准错误输出的去处

>|

重定向输出时忽略noclobber

-c noclobber

可以防止重定向时覆盖文件

<> 文件名

如果是一个设备文件,使用文件作为标准输入和标准输出

注意:

a.stdin、stdout和stderr的文件描述符分别时0,1,2

b.文件描述符与>之间没有空格

c.文件描述符默认值是1,1>可以简写为>

d.>后面的文件描述符前面一定要有&,否则会当作普通文件

f.&>file 与>& file意思完全相同,都等价于>file 2>&1

例:

  Scriptname > filename

  Scriptname >> filename

  Scriptname 2>&1

  Command &> filename

  Command 1>&2  简写为 command >&2

  Ls 2>a1 >&1 等同于 ls >a1 2>&1

2.进程替换 process substitution

 2.1命令替换:把一个命令的结果赋值给一个变量

   [root@server1 ~]# dir_contents=`ls -al`

   [root@server1 ~]# echo $dir_contents

 2.2进程替换:把一个进程的输出提供给另一个进程

    > (command)

    < (command)

3.比较操作符 comparison operator

  3.1字符串比较,安装ASCLL字符进行排序来比较

  1 #!/bin/bash
  2 # ASCII 字符<>比较
  3 veg1=carrots
  4 veg2=tomatoes
  5 if [[ "$veg1" < "$vge2" ]]
  6 then
  7   echo "$veg1 < $vge2"
  8 else
  9   echo "What kind of dictionary are yon using,anywho?"
 10 fi
 11 
 12 exit 0

 3.2 整数比较

5.17竖线

1. | 管道 pipe

[root@server1 ~]# cat *.sh | sort | uniq

[root@server1 ~]# cat file1 file2 | ls -l | sort

2. || 或-逻辑操作OR logical operator

在条件测试结构中,如果条件测试结构两边中的任意一边结果为true的话,||操作就会返回0(代表执行成功)

5.18 & 后台运行命令 Run job in background

1.命令后面跟一个&,表示在后台运行

例:[root@server1 ~]# sleep 10 &

[1] 1579

[root@server1 ~]# ps aux |  grep sleep

root       1579  0.0  0.0 107948   348 pts/0    S    17:30   0:00 sle

root       1581  0.0  0.0 112720   984 pts/0    S+   17:30   0:00 g

[root@server1 ~]# ps aux |  grep sleep

root       1583  0.0  0.0 112720   984 pts/0    S+   17:31   0:00 gre

[1]+  完成                  sleep 10 

  1 #!/bin/bash
  2 #l.sh
  3 for i in 1 2 3 4 5 6 7 8 9 10 # 第一循环
  4 do
  5   echo -n "$i"
  6 done & # 在后台执行这个循环
  7 echo
  8 
  9 for i in 11 12 13 14 15 16 17 18 19 20 #第二个循环
 10 do
 11   echo -n "$i"
 12 done # 正常地在前台执行这个循环
 13 echo
 14 exit 0

 

 2.&&与-逻辑操作AND logical operator

在条件测试结构的两边结构都为true时,&&才返回0(代表success)

5.19 - 减号Minus 连字符Hyphen、破折号Dash

 1、选项,前缀 option,prefix

例:ls -al

  1 #!/bin/bash
  2 if [ $file1 -ot $file2]
  3 then
  4   echo "File $file1 is older than $file2."
  5 fi
  6 
  7 
  8 param2=${param1:-$DEFAULTVAL}

 

 2.重定向stdin或stdout Redirection

例:

[root@server1 ~]# echo "whatever" | cat -

Whatever

[root@server1 ~]# bunzip1 -c 1.tar.bz2 | tar xvf –

[root@server1 ~]# (cd /source/directory && tar cf - .) | (cd /dest/directory && tar xpvf -)

[root@server1 ~]# cp -a /source/directory* /dest/directory

[root@server1 ~]# cp -a /source/directory* /source/directory/.[^.]* /dest/directory

[root@server1 ~]# file l.sh

  1 #!/bin/bash
  2 cp /root/file1 data.txtt
  3 file=data.txt
  4 head $file
  5 # 要插入的头的内容
  6 title="***This is the title of data text file***"
  7 echo $title | cat - $file > $file.new
  8 
  9 head data.txt.new
 10 exit 0

 例:备份最近一天当前目录下所有修改的文件

  1 #!/bin/bash
  2 # 备份最近一天当前目录下所有修改的文件
  3 # 使用-的stdin,stdout,及tar-gzip的手段
  4 # 默认的备份文件名,嵌入当前的时间
  5 BACKUPFILE=backup-$(date +%Y-%m-%d)
  6 # 如果没有传递参数给此脚本,则使用默认的文件名
  7 archive=${1:-$BACKUPFILE}
  8 tar cvf - `find . -mtime -1 -type f -print`> $archive.tar
  9 gzip $archive.tar
 10 # 如果当前目录中文件过多,或文件名包括空格时,有可能执行失败
 11 # 可以考虑修改为:
 12 # find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
 13 echo "Directory $PWD backup up in archive file \"$archive.tar.gz\"."
 14 exit 0

[root@server1 ~]# tar -ztf backup-2022-06-03.tar.gz

 3.先前的工作目录  Previous working directory

Cd – 回到先前的工作目录,其实时使用环境变量$  OLDPWD

4.减号 Minus

5.20 等号= Equal

1.等号 Equal

[root@server1 ~]# a=28

[root@server1 ~]# echo $a

28

2.字符串比较操作 String Comparison operator

  1 #!/bin/bash
  2 a=123
  3 b=12
  4 if [ "$a" = "$b" ]
  5 then
  6   echo yes
  7 else
  8   echo on
  9 fi

 

5.21 加号+ plus

1.加法算术 Addition arithmetic operator

2.正则表达式 regular expression

echo a11b | sed -ne `/a1\+b/p`

echo a11b | grep `a1\+b`

echo a11b | gawk `a1\+b`

3.选项 option

[root@server1 ~]# echo $l

[root@server1 ~]# set -u

[root@server1 ~]# echo $l

-bash: l: 为绑定变量

[root@server1 ~]# set +u

[root@server1 ~]# echo $l

5.22 %百分号 percen

1.取模 modulo

[root@server1 ~]# expr 5 % 3

2

[root@server1 ~]# expr 5 % 4

1

2.模式匹配 pattern matching

[root@server1 ~]# echo ${var%Pattern}

[root@server1 ~]# echo ${var%%Pattern}

5.23 ~ 波浪号 Tilde

1.~ 家目录 Home

$HOME

2.~+ 当前工作目录 current working directory

$PWD

3.~- 先前的工作目录 previous working directory

$OLDPWD

4.=~正则表达式匹配 regular expression match

5.24 ^ 脱字号,补字号 caret

1.行首 Beginning of line

2.大写抓换 Uppercase conversion

[root@server1 ~]# bash –version  bash版本在四以后

[root@server1 ~]# var=varMixedUpVariable

[root@server1 ~]# echo ${var}

varMixedUpVariable

[root@server1 ~]# echo ${var^}  第一个字母大写

VarMixedUpVariable

[root@server1 ~]# echo ${var^^}   全部大写

VARMIXEDUPVARIABLE

3.控制字符 control characters

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值