Shell基础

Leon
2021-08-23 / 0 评论 / 339 阅读 / 正在检测是否收录...

Shell基础

Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。

Shell.png

简单入门--Hello World

  1. 脚本格式
    脚本以#!/bin/bash开头(指定解析器)
  2. helloworld.sh中输入如下内容
#!/bin/bash
echo "helloworld"
  1. 脚本的常用执行方式
    第一种:采用bash或sh+脚本的相对路径或绝对路径(不用赋予脚本+x权限)

第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)

  1. 多命令处理
    在home/ts目录下新建ts.txt并写入I love ThunderSoft.
#!/bin/bash
cd /home/ts
touch ts.txt
echo "I love ThunderSoft." >>ts.txt

变量

变量默认为字符串类型不能进行数值运算。

  1. 常用系统变量

$HOME 当前用户home目录
$PWD 当前目录
$SHELL 默认解析器
$USER 当前用户

  1. 自定义变量
    A=1

=两边不能有空格,若有空格需要引号。
unset 释放变量

  1. 静态变量
    readonly B=1(不能unset)
  2. 全局变量
    export B 可供其它shell使用。
  3. 特殊变量
    $n 参数

$# 获取输入的所有参数
$* 获取所有参数(看做整体)
$@ 获取所有参数(分别获取)
$? 获取最后一次执行的状态
0正确执行 !0错误执行
file=/dir1/dir2/dir3/my.file.txt
可以用$分别替换得到不同的值:
${file#*/}:删掉第一个 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}:删掉最后一个 / 及其左边的字符串:my.file.txt
${file#*.}:删掉第一个 . 及其左边的字符串:file.txt
${file##*.}:删掉最后一个 . 及其左边的字符串:txt
${file%/*}:删掉最后一个 / 及其右边的字符串:/dir1/dir2/dir3
${file%%/*}:删掉第一个 / 及其右边的字符串:(空值)
${file%.*}:删掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}:删掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my

运算符

  1. "$((运算式))"或"$[运算式]"
  2. expr + , - , \*, /, % 加,减,乘,除,取余
    expr运算符间要有空格

For Example:

expr 2 + 3
expr `expr 2 + 3` \* 4

条件判断

  1. 基本语法

    [ condition ](注意condition前后要有空格)
    注意:条件非空即为true,[ ts ]返回true,[] 返回false。
  2. 常用判断条件

    1. 两个整数之间比较

    = 字符串比较

    -lt 小于(less than) -le 小于等于(less equal)

    -eq 等于(equal) -gt 大于(greater than)

    -ge 大于等于(greater equal) -ne 不等于(Not equal)

    1. 按照文件权限进行判断

    -r 有读的权限(read) -w 有写的权限(write)

    -x 有执行的权限(execute)

    1. 按照文件类型进行判断

    -f 文件存在并且是一个常规的文件(file)

    -e 文件存在(existence) -d 文件存在并是一个目录(directory)

    1. 多条件判断

    && 表示前一条命令执行成功时,才执行后一条命令

    || 表示上一条命令执行失败后,才执行下一条命令

流程控制

  1. if判断

    1. 基本语法

    if [ 条件判断式 ];then

    程序

    fi

    或者

    if [ 条件判断式 ]

    then

    程序

    fi

    1. 注意事项:

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

    (2)if后要有空格

    1. 输入一个数字,如果是1,则输出1,如果是2,则输出2,如果是其它,什么也不输出。

      #!/bin/bash
      if [ $1 -eq "1" ]
      then
      echo "1"
      elif [ $1 -eq "2" ]
      then
      echo "2"
      fi
  2. case语句

    1. 基本语法

    case $变量名 in

    "值1")

    如果变量的值等于值1,则执行程序1

    ;;

    "值2")

    如果变量的值等于值2,则执行程序2

    ;;

    …省略其他分支…

    *)

    如果变量的值都不是以上的值,则执行此程序

    ;;

    esac

    1. 注意事项:

    1) case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
    1) 双分号“;;”表示命令序列结束,相当于java中的break。
    1) 最后的“*)”表示默认模式,相当于java中的default。

    1. 输入一个数字,如果是1,则输出1,如果是2,则输出2,如果是其它,输出0。

      #!/bin/bash
      case $1 in
      "1")
      echo "1"
      ;;
      "2")
      echo "2"
      ;;
      *)
      echo "0"
      ;;
      esac
  3. for循环

    1. 基本语法1

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

    do

    程序

    done

    1. 从1加到100

      #!/bin/bash
      s=0
      for((i=0;i<=100;i++))
      do
      s=$[$s+$i]
      done
      echo $s
    2. 基本语法2
      for 变量 in 值1 值2 值3…

    do

    程序

    done

    1. 打印输入的所有数字

      #!/bin/bash
      for i in $*
      do
      echo " $i "
      done
  4. while循环

    1. 基本语法

while [ 条件判断式 ]

do

程序

done

  1. 从1加到100

    #!/bin/bashs=0i=1while [ $i -le 100 ]do=$[$s+$i]i=$[$i+1]doneecho $s

read读取控制台输入

  1. 基本语法

read(选项)(参数)

选项:

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

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

参数

变量:指定读取值的变量名

  1. #!/bin/bashread -t 7 -p "Please input you name." NAMEecho $NAME

    函数

  2. 系统函数

    1. basename

      1. 基本语法

      basename [string / pathname] [suffix]

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

      选项:

      suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。

      1. dirname文件绝对路径
  3. 自定义函数

    1. 基本语法
  [ function ] funname[()]

  {

  Action;

  [return int;]

  }

  funname
      必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。

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

   2. 计算输入两参数的和
  #!/bin/bash
  function sum(){
  s=0s=$[ $1 + $2 ]
  echo "$s"}
  read -p "Please input the number1: " n1;
  read -p "Please input the number2: " n2;
  sum $n1 $n2;

#### Shell工具

1. cut
   cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

   基本用法

   cut [选项参数]  filename

   | 选项参数 | 功能                         |
   | -------- | ---------------------------- |
   | -f       | 列号,提取第几列             |
   | -d       | 分隔符,按照指定分隔符分割列 |

   切割ts.txt第一列

cut -d " " -f 1 ts.txt


切ts.txt第二、三列

cut -d " " -f 2,3 ts.txt


在ts.txt文件中切割出ts

cat ts.txt | grep "ts" | cut -d " " -f 1


选取系统PATH变量值,第2个“:”开始后的所有路径:

echo $PATH | cut -d: -f 2-


切割ifconfig 后打印的IP地址

ifconfig eth0 | grep "inet addr" | cut -d: -f 2 | cut -d" " -f1


2. sed
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

基本用法

sed [选项参数]  ‘command’  filename

| 选项参数 | 功能                                  |
| -------- | ------------------------------------- |
| -e       | 直接在指令列模式上进行sed的动作编辑。 |

| 命令 | 功能描述                              |
| ---- | ------------------------------------- |
| *a*  | 新增,a的后面可以接字串,在下一行出现 |
| d    | 删除                                  |
| s    | 查找并替换                            |

将“ts”这个单词插入到ts.txt第二行下,打印。

sed '2a' ts sed.txt


注意:文件并没有改变

删除ts.txt文件所有包含wo的行

sed '/wo/d' ts.txt


将sed.txt文件中wo替换为ni

sed 's/wo/ni/g' ts.txt


注意:‘g’表示global,全部替换

将ts.txt文件中的第二行删除并将wo替换为ni

sed -e '2d' -e 's/wo/ni/g' ts.txt


3. awk

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

1. 基本用法

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

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

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

2. 选项参数说明

| 选项参数 | 功能                 |
| -------- | -------------------- |
| -F       | 指定输入文件折分隔符 |
| -v       | 赋值一个用户定义变量 |

搜索passwd文件以root关键字开头的所有行,并输出该行的第7列。

awk -F: '/^root/{print $7}' passwd


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

awk -F: '/^root/{print $1","$7}' passwd


注意:只有匹配了pattern的行才会执行action

只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell在最后一行添加"hi,/bin/ts"。

awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END{print "hi,/bin/ts"}' /etc/passwd


注意:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。

将passwd文件中的用户id增加数值1并输出

awk -v i=1 -F: '{print $3+i}' /etc/passwd


awk的内置变量

| 变量     | 说明                                   |
| -------- | -------------------------------------- |
| FILENAME | 文件名                                 |
| NR       | 已读的记录数                           |
| NF       | 浏览记录的域的个数(切割后,列的个数) |

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

awk -F: '{print "filename:" FILENAME ", linenumber:" NR ",columns:" NF}' /etc/passwd


切割IP

ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk -F " " '{print $1}'


查询sed.txt中空行所在的行号

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


4. sort
sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。

基本语法

sort(选项)(参数)

| 选项                       | 说明                     |
| -------------------------- | ------------------------ |
| -n                         | 依照数值的大小排序       |
| -r                         | 以相反的顺序来排序       |
| -t                         | 设置排序时所用的分隔字符 |
| -k                         | 指定需要排序的列         |
| 参数:指定待排序的文件列表 |                          |

​    按照“:”分割后的第三列倒序排序。

sort -t : -nrk 3 sort.sh


实例:什么时候下班。
实例地址:https://github.com/fuhailong1998/offWorkTime

!/bin/bash

@auther: Leon

echo 请输入您的上班时间。
read time
hour=${time%%.*}
min=${time##*.}
echo 想要误餐补吗?(18块)1要0不要。
read flag
case "$flag" in

1)
    if [ $min -gt 30 ]
    then

        hour=`expr $hour + 11`
        if [ `expr $min - 30` -lt 10 ]
        then
            min=0`expr $min - 30`
        else
            min=`expr $min - 30`
        fi
    elif [ $min -eq 30 ]
    then
        hour=`expr $hour + 11`
        min=00
    else
        hour=`expr $hour + 10`
        min=`expr $min + 30`
    fi
    echo 您需要$hour:$min下班。
    ;;
0)
    hour=`expr $hour + 8`
    echo 您需要$hour:$min下班。
    ;;
*)
    echo 输入有误!请规范输入,如"8.3"代表“8:03”。
    exit;
    esac

执行:

leon@fxkxb:~/sda/offWorkTime-main$ chmod +x offWorkTime
leon@fxkxb:~/sda/offWorkTime-main$ ./offWorkTime
请输入您的上班时间。
8.48
想要误餐补吗?(18块)1要0不要。
1
您需要19:18下班。

0

评论 (0)

取消