Shell学习

(注意:linux中要写shell脚本,必须是.sh的文件,eg: touch tesh.sh    ;vim test.sh      ;   sh test.sh)

Shell是一个命令行表达式,能接受应用程序或用户的命令,然后调用os内核。

Shell脚本固定以#!/bin/bash开头(指定为bash解析器)

bash和sh的关系:sh是bash的一个软链接

入门篇

  • 定义变量

      eg:  name="zhangsan"

 注:变量名和等号之间不能有空格。同时,变量名命名要遵循以下规则:
         1.命名只能用英文字母、数字、下划线,首字符不能以数字开头
         2.变量名之间不能有空格(有空格的话linux会把它当成一个命令),可以有_
         3.不能用标点符号
         4.不能用bash里的关键字(可用help查看关键字)

  • 声明静态变量(当虚拟机重启后就没了)

    readonly 变量名=值

  • 将变量提升为全局变量

    export 变量名

}

  • $n($0是脚本名 $1-.....是输入的参数1-....)
  • $#(获取所有输入参数的个数,常用于循环)
  • $*(代表命令行中所有的参数)
  • $@(也代表命令行中所有的参数,不过$@把每个参数区别对待)
  • $?(最后一次命令的返回状态,0代表正确执行,非0代表不正确执行)

 

  • 使用变量

     echo $ name
     echo ${name} 花括号可加,可不加

  • 删除变量

     unset name

注意:echo是个命令,所以需要有空格,只有赋值变量才没有空格

shell字符串

  • 字符串可以用单引号,也可以用双引号(但是双引号可以引用变量,单引号不行)

       str="hello world!"

       str='hello world!'

  •    获取字符串长度

       echo ${#str}

  •  提取字符串

 echo ${name:1} 它的意思是选取字符串从第1个到最后一个

echo ${name:0:3}它的意思是选取字符串从0到2

echo ${name:0:100}如果没有100个字符怎么办?最后它会选取到最后一个字符

 

shell数组

  • shell只支持一维数组,用括号表示,元素用空格符号分隔开

        array=(val1 val2 val3)

  • 通过下标定义数组

       array[0]=val1

      array[1]=val2

  •  读取数组元素

      echo ${array[0]}

  •   获取全部元素

     echo ${array[*]}

  •  获取数组长度

     echo ${#array[*]}

运算符

1.算术运算符

原生bash不支持简单的数学运算,但可以通过其他命令来实现

  • 两数相加、减、除(这里用的反引号`,而不是单引号')

       val=`expr 2 + 2`

       val=`expr 2 - 2`

       val=`expr 2 / 2`

也可以直接算val=$[2+2]

  (注意:表达式和运算符之间要有空格,比如2+2是不对的,要写成 2 + 2 ,完整的表达式要被``包含)

  • 两数相乘(要用到转义符号,*  →  \* )

       val=`expr 2 \* 2`

  • 取余

      val=`$a % $b`  (这里a、b是变量)

  •  赋值

      a=$b  (把b的值赋给a)

  • 比较相等

     [ $a == $b ]  (相同返回true,不同返回false)

  • 比较不等

     [ $a != $b ](不同返回true,相同返回false)

注意:条件表达式要放在方括号之间,而且必须有空格,

           比如:[$a == $b]就是错的,[ $a == $b ]才是对的

2.关系运算符

  • 运算符-eq(equal) :检测两数是否相等,相等返回true,不同返回false

       eg: [ $a -eq $b ]

  •  运算符-ne(not equal):检测两数是否不等,不等返回true,相等返回false

       eg:[ $a -ne $b ]

  • 运算符-gt(greater than):检测a>b?true:false

       eg:[ $a -gt $b ]

  • 运算符-lt(less than):检测a

       eg:[ $a -lt $b ]

  • 运算符-ge(greater equal):检测a>=b?true:false

      eg:[ $a -ge $b ]

  • 运算符-le(less equal):检测a<=b?true:false

     eg:[ $a -le $b ]

 

 3.布尔运算符

  • 非运算!

     eg:[ ! false ]返回true

  • 或运算-o

     eg:[ $ a -lt 20 -o $b -gt 100 ]

  • 与运算-a

    eg:[ $ a -lt 20 -a $b -gt 100 ]

4.逻辑运算符

  • &&

eg:[ $a -lt 100 && $b -gt 100]

  • ||

eg:[ $a -lt 100 || $b -gt 100]

5.字符串运算符

  • =:检测两字符串是否相等,相等返回true,不相等返回false

   eg:[ $a = $b ]

  • !=:检测两字符串是否不等,不等返回true,相等返回false

   eg:[ $a != $b ]

  • -z:检测字符串长度是否为0,为0返回true,不为0返回false

   eg:[ -z $a ]

  • -n:检测字符串长度是否不为0,不为0返回true,为0返回false

   eg:[-n $a ]

  • str:检测字符串是否不为空,不为空返回true

   eg:[ $a ]

条件控制语句

语法:

if  condition1

then 

     command1

elif condition2

then

      command2

else

     commandN

fi

Shell学习_第1张图片

for循环

第一种:

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

do

         command1

         .......

done

第二种:

for val in item1 item2 item3 ... itemN

do

        command1

        ....

        commandN

done

Shell学习_第2张图片

while循环

语法:

while comndition

do

       command

done

(这里可能会报错,可能是let的原因,因为/bin/sh指向dash而不是bash,dash不支持let命令

  所以,解决办法如下:输入sudo dpkg-reconfigure dash  

                                          输入密码

                                          出现个设定dash,选择“否”

Shell学习_第3张图片

Shell学习_第4张图片

标准输入与输出

把输出写入文件: ls -l > ls.txt(删除,覆盖效果)

把输出追加到文件:ls -l >> ls.txt(保留,追加效果)

 

标准错误

  • 通常情况下,标准和错误信息的输出混合在一起
  • 如果我想要将标准和错误信息混合输出到文件,可以用2>&1

        eg:python test.py >r.txt 2>&1

  • 使用bash shell时,可以用2<把标准错误流重定向到文件

案例:

重定向正确的输出:head -l /etc/* > result.log

重定向标准错误:head -l /etc/* 2 > error.log

分别重定向标准输出和标准错误:head -l /etc/* >result.log 2>error.log(常用)

 

Read读取控制台的输入

选项:

read -p:指定读取值时的提示符

read -t:指定读取值时等待时间(秒)

参数:变量

 

函数

系统函数

1.basename [ string / pathname ] [ suffix ]

(basename会删掉所有的前缀,包括最后一个‘/’字符,然后将字符串显示出来)

(如果后缀suffix被指定了,basename会将string/pathname中的suffix去掉)

eg:截取/home/zyy/test.txt路径的文件名称

basename /home/zyy/test.txt

basename /home/zyy/test.txt .txt

2.dirname 文件绝对路径

(从给定的绝对路径中去除文件名(非目录部分),然后返回剩下的路径(目录部分))

eg:获取test.sh的绝对路径

dirname /home/zyy/test.sh

 

自定义函数

1.基本语法

[ function ] fun_name[()]

{

        具体内容

       [ return $? ]

}

eg:计算两个输入参数的和

function sum()

{

       s=0;

       s=$[$1 + $2]

      echo $s

}

read -p "输入第一个参数:" p1

read -p "输入第二个参数:" p2

sum $p1 $p2

 

Shell工具

cut

cut负责在文件中剪切数据,从文件的每行剪切字节、字符、字段,并将这些字节、字符、字段输出

1.基本用法

cut [选项参数] filename

选项参数:-f :列号,提取第几列

                -d:分隔符,按照指定分隔符分割列

eg: 切割cut.txt第一列

Shell学习_第5张图片

eg:切割cut.txt第二、三列

eg:在cut文件中切割出“hao”

eg:选取系统PATH变量,第二个:开始后的路径(3-代表第三列及之后所有的)

sed

sed是一种流编辑器,一次处理一行的内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”。然后用sed命令处理缓冲区的内容,处理完成后把缓冲区的内容送往屏幕,接着处理下一行,如此反复。文件内容不会发生改变

1.基本用法

sed [选项参数] 'command' filename

选项参数:-e :多个命令时候加-e

                    a:新增,a后面能拼接字符串,在下一行出现

                    d:删除

                    s:查找并替换

eg:把“hello”这个词插入到sed.txt第二行下(a是插入,2a就是在第二行插入),打印

Shell学习_第6张图片

注意,文件内容不会发生变化

eg:删除sed.txt所有包含hello的行

eg:将sed.txt中的hello替换成world(加g是全局替换,不加只替换第一个)

eg:既把“hello”这个词插入到sed.txt第二行下,又将sed.txt中的hello替换成world

Shell学习_第7张图片

awk

和cut很像,只是处理形式不一样。

把文件逐行读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

1.基本用法

awk [选项参数] ‘pattern1 {action1} pattern2 {action2}...' filename

pattern:表示AWK在数据中查找的内容,就是匹配模式。

action:找到匹配内容时所执行的一系列命令。

选项参数:-F:输入文件的拆分符

                   -v:赋值一个用户定义变量

 

操作准备:sudo cp /etc/passwd ./

                    sudo chown xxx:xxx passwd

eg:搜索passwd文件以root开头的所有文件行(正则匹配),并输出改行的第7列

eg:搜索passwd文件以root关键字开头的所有行,并输出该行第1列和第7列中以“,”分割

     

eg:只显示/ect/passwd 的第一列和第七列,以逗号分隔,在所有行前面添加列名user,shell。在最后一行添加“zyy, /bin/hello”

eg:将passwd文件中的用户id(在第三列)增加数值1并输出

内置变量

FILENAME:文件名

NR:已读的记录数

NF:切割后列的个数

eg:统计passwd的文件名,每行的行号,每行的列数

eg:查询空行所在的行号(^:匹配字符串开始的位置;$:匹配字符串结尾的位置)

 sort

将文件进行排序,并将排序结果标准输出

1.基本语法

sort [选项] [参数]

选项:-n:按照数值大小排列

            -r:倒序排列

            -t:设置排序时的分隔字符

           -k:指定需要排序的列

数据准备:

Shell学习_第8张图片

eg:按照:分隔后的第2列倒叙排序

   Shell学习_第9张图片

   面试题:

1.使用linux查询file1中空行所在的行号

awk '/^$/ {print NR} ' file1

2.有文件file1内容如下:

  张三 40

 李四 60

 王五 99

用Linux命令计算第二列的和并输出。

cat  file1 | awk -F " " -v sum=0 '{ sum+=$2 }  END  {print sum} '

3.shell检查一个文件是否存在

Shell学习_第10张图片

4.用shell对文本中无序的一列数字排序

Shell学习_第11张图片

5.用shell查找当前文件夹/home下的所有文本内容中包含“hello”的文件名称

Shell学习_第12张图片

你可能感兴趣的:(瞎整)