zoukankan      html  css  js  c++  java
  • Shell脚本入门

    GNU bash, version 4.4.23

    0、前置知识

    01、文本结构

    1、脚本文件第一行指定解释器,用#!解释器表示
    	如/bin/bash、/usr/bin/python3
    2、第二行为注释,用#修饰
    3、其他的自由编写,注释也是
    

    02、执行权限

    脚本编写完成后会被执行,执行需要权限
    0 无权限
    1 r 读
    2 w 写
    4 x 执行
    chmod o+x  xx.sh  #添加执行权限 
    

    03、如何执行

    脚本文件中已经包含了解释器,权限足够的话,当前目录下直接即可执行
    如 ./hi.sh
    或者指定编译器bash hi.sh
    如果脚本所在的路径存在于环境变量中,那么直接使用文件名即可执行(任意位置)
    如hi.sh
    
    
    #!/bin/bash
    # this is shell script,name :hi.sh
    echo Hello
    
    ./hi.sh即可输出Hello
    

    1、基础语法

    1.1、变量

    Shell是脚本语言,定义变量比较随意,直接赋值即可,使用的时候,使用$取变量。

    关键字readonly、unset用于定义只读和删除变量,local定义局部变量,在函数中演示

    #!/usr/bin/bash
    
    myVal="Hello"  --直接定义即可
    echo $myVal --使用$获取变量
    
    myVal="World"  --修改变量
    echo "$myVal"
    
    readonly myVal="ok" --定义为只读变量
    myVal="nice"    --语句非法,无法修改
    
    
    unset myVal  --删除变量myVal,但是只读变量无法删除,此时报错
    
    

    1.2、引号

    Shell中有单引号、双引号、反引号甚至不加引号

    shell中可以不加引号,默认就是字符串

    单引号代表不解析,原样输出字符串

    双引号解析命令及变量,反引号用于使用命令,可以放在双引号中。

    echo `ls` --反引号中使用命令     output:  /  Hi.sh 
    
    echo "当前目录下执行ls命令: `ls`" --将反引号嵌入双引号中 
    

    1.3、字符串

    字符串(String)就是一系列字符的组合。字符串是 Shell 编程中最常用的数据类型之一(除了数字和字符串,也没有其他类型了,数组列表之类?)

    字符串可以使用{}包裹,用来处理更加复杂的操作,如拼接、截取、长度等

    str="Hello Shell"
    
    echo "${str}" #Hello Shell
    
    '#'用来取长度
    echo "长度是:${#str}"   #长度是:11
    
    拼接字符串,直接放一起
    echo "${str}""dd" 
    Hello Shelldd
    
    
    ': :截取字符串,位置:字符个数'
    echo "截取字符串:${str:1:5}"
    echo "截取字符串:${str::5}"
    echo "截取字符串:${str:0-3:5}" 
    截取字符串:ello 
    截取字符串:Hello
    截取字符串:ell
    

    1.4、 $#、$*、$@、$?

    Shell脚本执行时经常要从外部传递参数,在文件内部可以使用$接收。

    Shell中的特殊字符,$n在文件中指外部参数,0指代本文件名,其他指代参数顺序。

    $#指参数数量,$@和$*取所有参数。

    $?是上个命令或者函数退出状态

    ./hi.sh a b c
    
    echo $0   /usr/local/hi.sh
    echo $1	 a
    echo $2  b
    echo $3  c
    
    echo "total num :$#" total num :3
    echo "total:$@"  total:a b c
    
    
    echo $?  0 上个命令正常退出
    

    1.5、数组

    Shell 也支持数组,没有限制数组的大小,理论上可以存放无限量的数据,只支持一维数组。

    使用x=(z y z)格式声明,使用x[n] 取值

    arr=(1 2 3 4 5)
    echo "默认从0开始: $arr"
    echo "所有值: ${arr[*]}"
    echo "数量: ${#arr[*]}"    还是使用'#'获取数量
    
    默认从0开始: 1
    所有值: 1 2 3 4 5
    数量: 5
    
    arr[6]="ok"
    echo "所有值: ${arr[*]}"
    所有值: 1 2 3 4 5 ok
    
    unset arr[6] 删除元素
    unset arr  删除数组
    

    1.6、(())、流程

    shell中的(())用来处理数学运算(let也行),使用if then fi else等关键字处理。

    a=20
    
    if ((a>30))
    then
        ((a+=10))
        echo $a
    elif ((a<10))
    then
        echo $a
    else
        echo "no"
    
    当然使用:分割后会好看一点
    if ((a>30)) ; then
        ((a+=10))
        echo $a
    elif ((a<10)) ; then
        echo $a
    else
        echo "no" ; fi
    

    shell中的循环使用for控制,可以使用c或者python风格。也有whileunyilselect等循环,1.9中

    #c风格的流程
    for((i=0;i<10;i++))
    do
        echo "C-For: $i"
    done
    
    
    
    #python风格
    for i in 0 2 3 4 5
    do
        echo "Python_For :$i"
    done
    

    1.7、函数

    shell中的函数使用function声明,同样使用$取参数。

    调用的时候直接使用函数名即可

    function sum() {
        n=0             //这里的变量外部也可以访问,使用local修饰则只能在函数中
        for i in $@
        do
            ((n+=i))
        done
        echo "$n"
    }
    
    sum 1 2 3 4  //10
    echo $n      //10
    sum          //0
    
    echo $? //0 上一个命令或函数退出的状态,正常退出则为0
    

    1.8、read

    read 用于从命令行输入,像C的scan,python的input.

    参数-p 显示提示信息,-a将数据给数组

    read -p "Enter some information > " name url age  //tom 10 www.google.com
    echo $name  $age $url     //tom 10 www.google.com
    
    
    read -a arr      //a b c d
    
    echo ${arr[*]}   //a b c d
    

    1.9、循环

    shell中除了for循环外,还有while、until、select in循环以及case in结构

    while、until循环

    x=8
    while ((x<10)) ; do 
        echo "ok"
        ((x+=1))
    done       
    //ok
    //ok
    
    until和 while相反,用一个就行了。
    

    select in循环

    select in 循环用来增强交互性,它可以显示出带编号的菜单,用户输入不同的编号就可以选择不同的菜单,并执行不同的功能。
    select in 是 Shell 独有的一种循环,非常适合终端(Terminal)这样的交互场景。

    arr=("Shell" "Python" "JavaScript")
    
    select x in ${arr[*]};do
        echo "$x"
    done
    echo "You have selected $x"
    
    1) Shell
    2) Python
    3) JavaScript 
    #? 1               //输入编号
    #? Shell
    2
    Python
    #? 3
    #? JavaScript
    ^D           //Crtl+D代表终止,所以上一个就是你的选择
    
    You have selected JavaScript
    

    select in 和用户交互,不会主动终止,使用break让其结束。

    case in常和case in 一起用,用来处理条件。

    case in )

    echo "What is your favourite OS?"
    select name in "Linux" "Windows" "Mac OS" "UNIX" "Android"
    do
        case $name in
            "Linux")
                echo "Linux是一个类UNIX操作系统,它开源免费,运行在各种服务器设备和嵌入式设备。"
                break
                ;;
            "Windows")
                echo "Windows是微软开发的个人电脑操作系统,它是闭源收费的。"
                break
                ;;
            "Mac OS")
                echo "Mac OS是苹果公司基于UNIX开发的一款图形界面操作系统,只能运行与苹果提供的硬件之上。"
                break
                ;;
            "UNIX")
                echo "UNIX是操作系统的开山鼻祖,现在已经逐渐退出历史舞台,只应用在特殊场合。"
                break
                ;;
            "Android")
                echo "Android是由Google开发的手机操作系统,目前已经占据了70%的市场份额。"
                break
                ;;
            *)
                echo "输入错误,请重新输入"
        esac
    done
    
    
    
    1) Linux
    2) Windows
    3) Mac OS
    4) UNIX
    5) Android
    #? What is your favourite OS?
    2
    Windows是微软开发的个人电脑操作系统,它是闭源收费的。
    

    1.10、test、[[]]

    test 是 Shell 内置命令,用来检测某个条件是否成立。test 通常和 if 语句一起使用,并且大部分 if 语句都依赖 test。

    test 命令有很多选项,可以进行数值、字符串和文件三个方面的检测。

    test 命令比较奇葩,>、<、== 只能用来比较字符串,不能用来比较数字,比较数字需要使用 -eq、-gt
    等选项;不管是比较字符串还是数字,test 都不支持 >= 和 <=。有经验的程序员需要慢慢习惯 test 命令的这些奇葩用法。

    比较数字

    read a
    
    if test $a -eq 10; then
        echo "=10"
    elif test $a -gt 10 && test $a -lt 20 ;then
        echo "20>a>10"
    elif test $a -le 20 ; then
        echo "<=20"
    else
        echo "no"
    f
    

    比较字符串

    选 项 作 用
    -z str 判断字符串 str 是否为空。
    -n str 判断宇符串 str 是否为非空。
    str1 = str2 str1 == str2 ===是等价的,都用来判断 str1 是否和 str2 相等。
    str1 != str2 判断 str1 是否和 str2 不相等。
    str1 > str2 判断 str1 是否大于 str2。>>的转义字符,这样写是为了防止>被误认为成重定向运算符。
    str1 < str2 判断 str1 是否小于 str2。同样,<也是转义字符。
    a=""
    
    if test -z "$a" ; then
        echo "ok"
    fi
    
    //ok
    
    

    比较文件

    文件类型判断
    选 项 作 用
    -b filename 判断文件是否存在,并且是否为块设备文件。
    -c filename 判断文件是否存在,并且是否为字符设备文件。
    -d filename 判断文件是否存在,并且是否为目录文件。
    -e filename 判断文件是否存在。
    -f filename 判断文件是否存在,井且是否为普通文件。
    -L filename 判断文件是否存在,并且是否为符号链接文件。
    -p filename 判断文件是否存在,并且是否为管道文件。
    -s filename 判断文件是否存在,并且是否为非空。
    -S filename 判断该文件是否存在,并且是否为套接字文件。
    文件权限判断
    选 项 作 用
    -r filename 判断文件是否存在,并且是否拥有读权限。
    -w filename 判断文件是否存在,并且是否拥有写权限。
    -x filename 判断文件是否存在,并且是否拥有执行权限。
    -u filename 判断文件是否存在,并且是否拥有 SUID 权限。
    -g filename 判断文件是否存在,并且是否拥有 SGID 权限。
    -k filename 判断该文件是否存在,并且是否拥有 SBIT 权限。
    文件比较
    选 项 作 用
    filename1 -nt filename2 判断 filename1 的修改时间是否比 filename2 的新。
    filename -ot filename2 判断 filename1 的修改时间是否比 filename2 的旧。
    filename1 -ef filename2 判断 filename1 是否和 filename2 的 inode 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法

    [[]][[ ]]是 Shell 内置关键字,它和 test 命令类似,也用来检测某个条件是否成立。
    test 能做到的,[[ ]] 也能做到,而且 [[ ]] 做的更好;test 做不到的,[[ ]] 还能做到。可以认为 [[ ]] 是 test 的升级版,对细节进行了优化,并且扩展了一些功能。

    a=""
    
    if [[ -z $a ]]; then
        echo "ok"
    fi
    
    //ok
    
    

    [[]]支持正则表达式

    a="okok"
    
    if [[ $a=~^o ]]; then
        echo "ok"
    fi
    
    
  • 相关阅读:
    HDU 5642 King's Order 动态规划
    HDU 5640 King's Cake GCD
    HDU 5641 King's Phone 模拟
    HDU 5299 Circles Game 博弈论 暴力
    HDU 5294 Tricks Device 网络流 最短路
    HDU 5289 Assignment rmq
    HDU 5288 OO’s Sequence 水题
    星际争霸 虚空之遗 人族5BB 操作流程
    Codeforces Beta Round #3 D. Least Cost Bracket Sequence 优先队列
    Codeforces Beta Round #3 C. Tic-tac-toe 模拟题
  • 原文地址:https://www.cnblogs.com/cgl-dong/p/14052444.html
Copyright © 2011-2022 走看看