Linux Shell

1.Shell中的特殊变量

1.1 $n 命令-获取脚本命令的参数

基本语法:$n
n为数字,$0代表该脚本的名称,$1-$9代表第一到第九个参数,10以上的参数用大括号表示${10}
Shell脚本 - 图1

1.2 $# 命令-统计输入参数的个数

基本语法:$#
获取所有输入参数的个数,常用于循环
Shell脚本 - 图2

1.3 $*$@ 命令-获取输入的所有参数

基本语法: $*$@
$* :*变量代表命令行中所有参数,并把所有参数当作一个整体看待
$@ :@代表命令行所有参数, $@ 将所有参数区分对待
Shell脚本 - 图3

1.4 $? 命令-最后一次执行的命令的返回状态

基本语法:$?
$?:最后一次执行的命令的返回状态,变量值为0,则命令执行正确,变量值为非0,则命令有误。
Shell脚本 - 图4

1.5Shell脚本的定义

脚本以 #!/bin/bash 开头

  1. #!/bin/bash

Shell脚本中将执行的命令返回给变量,使用反引号将执行的命令引用

  1. a = `pwd`

1.6常用系统变量

1.6.1查看系统变量的值

$HOME,$PWD,$SHELL,$USER

1.6.2显示当前Shell的所有变量

root@Fcscanf:~# set

2.自定义变量

2.1基本语法

  1. 定义变量:变量 = 值
  2. 撤销变量:unset 变量
  3. 声明静态变量:readonly 变量,注意:不能unset

    2.2变量的定义规则

  4. 变量名称可以由字母,数字和下画线组成,但是不能以数字开头,环境变量名建议大写

  5. 等号两侧不能有空格
  6. 在Bash中,变量默认的都是字符串类型,无法进行数值运算
  7. 变量的值如果有空格,需要使用引号括起来

    2.3操作实例

    Shell脚本 - 图5

    2.4变量定义为全局变量供其他shell程序使用

    全局变量定义:**export** 变量名
    Shell脚本 - 图6

    3.Shell运算符

    3.1基本语法

  8. $((运算式))”或“$[运算式]

  9. expr +,-,\*,/,%:加,减,乘,除,取余(expr运算符间要有空格)

Shell脚本 - 图7

4.条件判断

4.1基本语法

[condition] (注意condition前后要有空格)
条件非空即为true
Shell脚本 - 图8

4.2常用判断条件

4.2.1两个整数之间比较

  1. = 字符串比较
  2. -lt 小于(less than)
  3. -le 小于等于(less equal)
  4. -eq 等于 (equal)
  5. -gt 大于 (greater than)
  6. -ge 大于等于 (greater equal)
  7. -ne 不等于 (Not equal)

    4.2.2按照文件权限进行比较

  8. -r 读的权限read

  9. -w 写的权限write
  10. -x 执行的权限execute

    4.2.3按照文件类型进行判断

  11. -f 文件存在并且是一个常规文件file

  12. -e 文件存在existence
  13. -d 文件存在并且是一个目录directory

Shell脚本 - 图9

5.流程控制

5.1 if判断

5.1.1基本语法

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

5.1.2注意事项

  1. [ 条件判断式 ],中括号和条件判断式之间必须有空格
  2. if后要有空格

    5.1.3操作实例

    #!/bin/bash
    if [ $1 -eq 1 ]
    then
         echo "hello world"
    elif [ $1 -eq 2 ]
    then
         echo "hello world 2"
    fi
    

    Shell脚本 - 图10

    5.2 case语句

    5.2.1基本语法

    case $ 变量名 in
    "值1")
    程序-如果变量值为值1,执行此语句
    ;;             //相当于其他语言的break
    "值2")
    程序-如果变量值为值2,执行此语句
    ;;
    *)               //相当于其他语言的default
    程序-找不到以上值执行此语句
    ;;
    esac
    

    5.2.2注意事项

  3. case行尾必须为单词“in”,每一个模式必须以右括号“)”结束

  4. 双分号“;;”表示命令序列结束,相当于Java中的break
  5. 最后的”*)“表示默认模式,相当于Java中的default

    5.2.3操作实例

    #!/bin/bash
    case $1 in
     1)
             echo "1 toch"
                ;;
     2)
             echo "2 toch"
             ;;
     *)
     echo "more toch"
             ;;
    esac
    

    Shell脚本 - 图11

    5.3 for循环

    5.3.1基本语法

    for (( 初始值;循环控制条件;变量变化 ))
    do
     程序
    done
    或将输入的值赋给变量进行循环输出
    for 变量 in 值1 值2 值3 ...
    do
     程序
    done
    

    5.3.2操作实例

    A.定义值范围的循环

    #!/bin/bash
    s=0
    for((i=1;i<=100;i++))
    do
         s=$[$s+$i]
    done
    echo $
    

    Shell脚本 - 图12

    B.赋值输出示例

    #!/bin/bash
    for i in $*
    do
         echo "fcc is $i"
    done
    

    Shell脚本 - 图13

    #!/bin/bash
    for i in $*
    do
         echo "fcc is $i"
    done
    for j in $@
    do
         echo "fcc is $j"
    done
    

    整体与分开的参数传递

    #!/bin/bash
    for i in "$*"
    do
         echo "fcc is $i"
    done
    for j in "$@"
    do
         echo "fcc is $j"
    done
    

    5.4 while循环

    5.3.1基本语法

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

    5.3.2注意事项

  6. while后面要用空格隔开

  7. []“里的条件判断式要用空格隔开

    5.3.3操作实例

    #!/bin/bash
    s=0
    i=1
    while [ $i -le 100 ]
    do
     s=$[$s + $i]
     i=$[$i + 1]
    done
    echo $
    

    Shell脚本 - 图14

    6.read读取控制台输入

    6.1基本语法

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

    6.2操作示例

    #!/bin/bash
    read -t 7 -p "Enter your name in 7 seconds" NAME
    echo $NAME
    

    Shell脚本 - 图15

    7.函数

    7.1系统函数

    7.1.2 basename

    基本语法:basename [string/pathname] [suffix]
    basename命令会删除所有前缀包括最后一个(‘/‘)字符,然后将字符串显示出来
    选项:
    suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉
    Shell脚本 - 图16

    7.1.3 dirname

    基本语法:dirname 文件绝对路径
    从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
    Shell脚本 - 图17

    7.2自定义函数

    7.2.1基本语法

    [ function ] function[()]
    {
    Action;
    [return int;]
    }
    funname
    

    7.2.2注意事项

  8. 函数必须在调用之前声明

  9. 函数返回值只能通过$?系统变量获得,可以显示加:return,如果不加,将以最后一条命令运行结果作为返回值。return后跟数值n(0-255)

    7.2.3操作案例

    计算两个输入参数的和

    #!/bin/bash
    function sum()
    {
     s=0
     s=$[ $1 + $2 ]
     echo "$s"
    }
    read -p "Please input the number1:" n1;
    read -p "Please input the number2:" n2;
    sum $n1 $n2
    

    Shell脚本 - 图18

    8.Shell工具

    8.1 cut-剪切数据并输出

  10. 基本语法

    1. cut [选项参数] filename:默认分隔符是制表符
  11. 选项参数说明
    1. -f :列号,提取第几列
    2. -d:分隔符,按照指定分隔符分隔列

Shell脚本 - 图19
Shell脚本 - 图20

8.2 sed-流编辑器

  1. 基本语法
    1. sed [参数列表] 'command' filename
  2. 选项参数说明
    1. -e:直接在指令列模式进行sed的动作编辑
  3. 命令功能描述
    1. a:新增,a的后面可以接字串,在下一行出现
    2. d:删除
    3. s:查找并替换
  • 在输出流插入

Shell脚本 - 图21

  • 在输出流删除

Shell脚本 - 图22

  • 在输出流替换内容,g=global表示全部替换

Shell脚本 - 图23

  • 将第二行删除并替换

Shell脚本 - 图24

8.3 awk-文本分析工具

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

8.3.1基本语法

  1. 基本语法:awk [选项参数] 'pattern1{action1} pattern2{action2} ...' filename
    1. pattern:表示awk在数据中查找的内容,就是匹配模式
    2. action:在找到匹配内容时所执行的命令
  2. 选项参数说明
    1. -F:指定输入文件折分隔符
    2. -v:赋值一个用户定义变量
  3. 内置变量

    1. FILENAME:文件名
    2. NR:已读的记录数
    3. NF:浏览记录的域的个数(切割后,列的个数)

      8.3.2操作实例

      root@Fcscanf:/home/fc# awk -F: '/^root/{print $7}' passwd
      /bin/bash
      root@Fcscanf:/home/fc# awk -F: '/^root/{print $1","$7}' passwd
      root,/bin/bash
      root@Fcscanf:/home/fc# awk -F: 'BEGIN{print "user,shell"} {print $1","$7} END{print "dahai,bin/sh"}' passwd
      user,shell
      root,/bin/bash
      daemon,/usr/sbin/nologin
      bin,/usr/sbin/nologin
      sys,/usr/sbin/nologin
      sync,/bin/sync
      games,/usr/sbin/nologin
      man,/usr/sbin/nologin
      lp,/usr/sbin/nologin
      mail,/usr/sbin/nologin
      news,/usr/sbin/nologin
      uucp,/usr/sbin/nologin
      proxy,/usr/sbin/nologin
      www-data,/usr/sbin/nologin
      backup,/usr/sbin/nologin
      list,/usr/sbin/nologin
      irc,/usr/sbin/nologin
      gnats,/usr/sbin/nologin
      nobody,/usr/sbin/nologin
      systemd-network,/usr/sbin/nologin
      systemd-resolve,/usr/sbin/nologin
      syslog,/usr/sbin/nologin
      messagebus,/usr/sbin/nologin
      _apt,/usr/sbin/nologin
      lxd,/bin/false
      uuidd,/usr/sbin/nologin
      dnsmasq,/usr/sbin/nologin
      landscape,/usr/sbin/nologin
      sshd,/usr/sbin/nologin
      pollinate,/bin/false
      dahai,bin/sh
      root@Fcscanf:/home/fc# awk -F: -v i=1 '{print $3+$i}' passwd
      0
      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      Shell脚本 - 图25
      Shell脚本 - 图26
      Shell脚本 - 图27
      Shell脚本 - 图28
      Shell脚本 - 图29

      8.4 sort-将文件排序输出

      8.4.1基本语法

  4. 基本语法:sort(选项)(参数)

    1. -n:按照数值的大小排序
    2. -r:以相反的顺序来排序
    3. -t:设置排序时所用的分隔字符
    4. -k:指定需要排序的列

      8.4.2操作示例

      root@Fcscanf:/home/fc# touch sort.sh
      root@Fcscanf:/home/fc# vim sort.sh
      root@Fcscanf:/home/fc# cat sort.sh
      bb:40:5.4
      bd:20:4.2
      xz:50:2.3
      cls:10:3.5
      ss:30:1.6
      root@Fcscanf:/home/fc# sort -t : -nrk 2 sort.sh
      xz:50:2.3
      bb:40:5.4
      ss:30:1.6
      bd:20:4.2
      cls:10:3.5
      root@Fcscanf:/home/fc#
      

Shell脚本 - 图30

9.企业面试题

11.1京东

  1. 使用Linux命令查询file 1中空行所在的行号

awk '/^/{print NR}' sed.txt

  1. 有文件chengji.txt内容如下:

张三 40
李四 50
王五 60
使用Linux命令计算第二列的和并输出
cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}'

11.2搜狐&和讯网

  1. Shell脚本如何检查一个脚本是否存在,如果不存在该如何处理?

    #!/bin/bash
    if [ -f file.txt ]
    then
    echo "文件存在!"
    else
    echo "文件不存在!"
    fi
    

    11.3新浪

  2. 用shell写一个脚本,对文本中无序的一列数字排序

    sort -n test.txt | awk '{a+$0;print$0}END{print "SUM="a}'
    

    11.4金和网络

  3. 使用shell脚本写出查找当前文件夹/home下的所有文件内容中包含有字符“shen”的文件的名称

    grep -r "shen" /home | cut -d ":" -f 1