shell编程 订阅
shell 是操作系统的最外层。shell 合并编程语言以控制进程和文件,以及启动和控制其它程序。shell 通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出来管理您与操作系统之间的交互。 展开全文
shell 是操作系统的最外层。shell 合并编程语言以控制进程和文件,以及启动和控制其它程序。shell 通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出来管理您与操作系统之间的交互。
信息
类    别
操作系统
常    见
在ARM技术里有很广的应用
应    用
编程技术
外文名
shell
Shell编程基本概述
shell 提供了与操作系统通信的方式。此通信以交互的方式(来自键盘的输入立即操作)或作为一个 shell 脚本执行。shell 脚本是 shell 和操作系统命令的序列,它存储在文件中。当登录到系统中时,系统定位要执行的 shell 的名称。在它执行之后,shell 显示一个命令提示符。普通用户的此提示符通常是一个 $(美元符)。当提示符下输入命令并按下 Enter 键时,shell 对命令进行求值,并尝试执行它。取决于命令说明,shell 将命令输出写到屏幕或重定向到输出。然后它返回命令提示符,并等待您输入另一个命令。命令行是输入所在的行。它包含 shell 提示符。每行的基本格式如下:$ 命令参数(一个或多个)shell 视命令行的第一个字(直到第一个空白空格)为命令,所有后继字为自变量。在Windows环境下,不论是使用Visual C++还是Delphi或是其他一些软件开发工具开发的应用程序,尽管存在着差别,但有一点是相同的:都是运行于Windows操作系统之下的。在程序开发过程中也经常要在自己的应用程序中加入一些Windows系统本身就有的功能,比如文件的拷贝、删除、查找以及运行程序等等。而这些功能在Windows操作系统下都是具备的,显然如果能直接从系统中调用这些功能将不仅仅减少程序的大小和开发人员的工作量,而且由于是直接通过操作系统来完成这些功能,将会大大减小这部分程序出现异常错误的概率。Windows系统虽说也存在不少错误,但常用功能的错误还是比较少的,而且通过补丁程序可以更低限度减少系统错误,因此程序员可以将调试检错的注意力放在应用程序的其他地方,对于调用系统功能这部分代码则可以不必投入太大的精力去调试,因为这部分调试的工作在操作系统发布的时候就已经由微软做好了。本文通过外壳编程,实现了搜寻文件、运行程序、控制工具条、最大最小化窗口的功能。
收起全文
精华内容
下载资源
问答
  • Shell编程

    万次阅读 2019-10-21 09:42:07
    大数据学习基础:Shell编程

    一、Shell 概述

    Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。
    在这里插入图片描述

    二、Shell 解析器

    ① Linux 提供的 Shell 解析器

    [root@hadoop ~]# cat /etc/shells
    /bin/sh
    /bin/bash
    /sbin/nologin
    /usr/bin/sh
    /usr/bin/bash
    /usr/sbin/nologin
    

    ② sh 和 bash 的关系

    [root@hadoop bin]# ll | grep bash
    -rwxr-xr-x  1 root root      960472 Dec  7  2016 bash
    lrwxrwxrwx  1 root root           4 Aug 18  2017 sh -> bash
    

    可以看出shbash的软连接

    ③ Centos默认的解析器是bash

    [root@izwz923wscm1q3eumry71kz bin]# echo $SHELL
    /bin/bash
    

    三、Shell 脚本入门

    ① 脚本格式

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

    ② 第一个 Shell 脚本:helloworld

    [root@hadoop shell]$ touch helloworld.sh
    [root@hadoop shell]$ vi helloworld.sh
    
    # 在helloworld.sh中输入如下内容
    #!/bin/bash
    echo "helloworld"
    

    ③ 脚本的常用执行方式

    1)采用bashsh+脚本的相对路径或绝对路径(不用赋予脚本+x权限)

    sh+脚本的相对路径/绝对路径 或 bash+脚本的相对路径/绝对路径
    [root@hadoop shell]$ bash helloworld.sh 
    Helloworld
    [root@hadoop shell]$ sh helloworld.sh 
    Helloworld
    

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

    [root@hadoop shell]$ chmod 777 helloworld.sh
    [root@hadoop shell]$ ./helloworld.sh 
    Helloworld
    

    注意:第一种执行方法,本质是bash解析器帮你执行脚本,所以脚本本身不需要执行权限。第二种执行方法,本质是脚本需要自己执行,所以需要执行权限。

    ④ 多命令处理

    需求:在/root目录下创建一个note.txt,在note.txt文件中增加I love shell

    [root@hadoop shell]$ touch batch.sh
    [root@hadoop shell]$ vi batch.sh
    
    #!/bin/bash
    cd /root
    touch cls.txt
    echo "I love cls" >>cls.txt
    

    四、Shell 变量

    系统变量

    常用系统变量:$HOME、$PWD、$SHELL、$USER

    查看系统变量的值:
    	[root@hadoop shell]$ echo $HOME
    
    显示当前Shell中所有变量:
    	[root@hadoop shell]$ set
    

    自定义变量

    基本语法:

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

    变量定义规则:

    • 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写
    • 等号两侧不能有空格
    • bash中,变量默认类型都是字符串类型,无法直接进行数值运算
    • 变量的值如果有空格,需要使用双引号或单引号括起来

    特殊变量

    $n

    基本用法:$n(功能描述:n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}

    [root@hadoop shell]# touch parameter.sh 
    [root@hadoop shell]# vim parameter.sh
    
    #!/bin/bash
    echo "$0  $1   $2"
    
    [root@hadoop shell]# chmod 777 parameter.sh
    
    [root@hadoop shell]# ./parameter.sh cls  xz
    ./parameter.sh  cls   xz
    

    $#

    基本用法:$#(功能描述:获取所有输入参数个数,常用于循环)。

    [root@hadoop shell]# vim parameter.sh
    
    #!/bin/bash
    echo "$0  $1   $2"
    echo $#
    
    [root@hadoop shell]# chmod 777 parameter.sh
    
    [root@hadoop shell]# ./parameter.sh cls  xz
    parameter.sh cls xz 
    2
    

    $*$@

    基本用法:

    $*:(功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
    $@:(功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)

    [root@hadoop shell]# vim parameter.sh
    
    #!/bin/bash
    echo "$0  $1   $2"
    echo $#
    echo $*
    echo $@
    
    [root@hadoop shell]# bash parameter.sh 1 2 3
    1 2 3
    3
    1 2 3
    1 2 3
    

    $?

    基本用法:$?(功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了)

    [root@hadoop shell]# ./helloworld.sh 
    hello world
    [root@hadoop shell]# echo $?
    0
    

    五、运算符

    基本语法:

    • $((运算式))$[运算式]
    • expr + , - , *, /, %

    注意:expr运算符间要有空格

    ① 计算3+2的值

    [root@hadoop shell]# expr 2 + 3
    5
    

    ② 计算(2+3)X4的值

    [root@hadoop shell]# S=$[(2+3)*4]
    [root@hadoop shell]# echo $S
    

    六、条件判断

    基本语法:[ condition ](注意condition前后要有空格),注意:条件非空即为true,[] 返回false

    常用判断条件:

    ① 两个整数之间比较

    符号 说明
    = 字符串比较
    -lt 小于(less than)
    -le 小于等于(less equal)
    -eq 等于(equal)
    -gt 大于(greater than)
    -ge 大于等于(greater equal)
    -ne 不等于(Not equal)

    ② 按照文件权限进行判断

    符号 说明
    -r 有读的权限(read)
    -w 有写的权限(write)
    -x 有执行的权限(execute)

    ③ 按照文件类型进行判断

    符号 说明
    -f 文件存在并且是一个常规的文件(file)
    -e 文件存在(existence)
    -d 文件存在并是一个目录(directory)

    案例:

    ① 23是否大于等于22

    [root@hadoop shell]# [ 23 -ge 22 ]
    [root@hadoop shell]# echo $?
    0
    

    ②​ helloworld.sh是否具有写权限

    [root@hadoop shell]# [ -w helloworld.sh ]
    [root@hadoop shell]# echo $?
    0
    

    /home/shell/cls.txt目录中的文件是否存在

    [root@hadoop shell]# [ -e /home/shell/cls.txt ]
    [root@hadoop shell]# echo $?
    1
    

    七、流程控制

    7.1 if 判断

    基本语法:

    if-fi

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

    if-elif-else-fi

    if [ 条件判断式 ]
    	then
    		程序
    elif[ 条件判断式 ]
    	then
    		程序
    else
    	程序
    fi
    

    注意事项:

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

    案例:

    ①单个if流程的使用

    if [ $1 -ge 3 ];then
    	echo "hello if"
    fi
    

    if-elif-else的使用

    #!/bin/bash
    if [ $1 -ge 3 ]
    	then
    		echo "hello if"
    elif [ $1 -ge 2 ]
    	then
    		echo "hello if2"
    else
    	echo "hello if3"
    fi
    

    7.2 case 语句

    基本语法:

    case $变量名 in
    "值1")
    	程序1
    ;;
    "值2")
    	程序2
    ;;
    *)
    	其他程序
    ;;
    esac
    

    注意事项:

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

    案例:

    #!/bin/bash
    case $1 in
    "1")
    	echo "Hello A"
    ;;
    "2") 
    	echo "Hello B"
    ;;
    *)
    	echo "Hello C"
    ;;
    esac
    

    7.3 for 循环

    基本语法:

    ①第一种

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

    案例:

    s=0
    for((i=0;i<100;i++))
    do
    	s=$[ s+i ]
    done
    echo $s
    

    ②第二种

    for 变量 in 值1 值2 值3...
    do
    	程序
    done
    

    案例:

    for i in "$@"
    do
    	echo "I love this $i"
    done
    

    注意:$*$@的区别:

    当不被双引号包围的时候,$*$@参数均会以$1$2$n的的形式输出。当被双引号包围的时候,$*参数会被当做一个整体输出

    7.4 whilie 循环

    基本语法:

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

    案例:

    #!/bin/bash
    i=5
    while [ $i -gt 1 ]
    do 
    	i=$[ i =$i-1 ]
    	echo $i
    done
    

    八、read 读取控制台输入

    基本语法: read (选项) (参数)

    选项:

    • -p:指定读取值时的提示符;
    • -t:指定读取值时等待的时间(秒)

    参数:变量,指定读取值的变量名

    [root@hadoop shell]$ touch read.sh
    [root@hadoop shell]$ vim read.sh
    #!/bin/bash
    read -t 7 -p "Enter your name in 7 seconds " NAME
    echo $NAME
    
    [root@hadoop shell]$ ./read.sh 
    Enter your name in 7 seconds ming
    ming
    

    九、函数

    9.1 系统函数

    ①basename

    语法basename [string / pathname] [suffix]

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

    选项suffix为后缀,如果suffix被指定了,basename会将pathnamestring中的suffix去掉。

    案例:

    截取该/root/test.txt路径的文件名称

    [root@hadoop shell]$ basename /root/test.txt 
    test.txt
    [root@hadoop shell]$ basename /root/test.txt .txt
    test
    

    ②dirname

    语法dirname 文件绝对路径

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

    案例:
    获取/root/test.txt文件的路径

    [root@hadoop shell]$ dirname /root/test.txt 
    /root
    

    9.2 自定义函数

    语法:

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

    说明:

    • 必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译
    • 函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)

    案例:

    计算两个输入参数的和

    [root@hadoop shell]$ touch fun.sh
    [root@hadoop shell]$ vim fun.sh
    
    #!/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;
    
    [root@hadoop shell]$ chmod 777 fun.sh
    [root@hadoop shell]$ ./fun.sh 
    Please input the number1: 2
    Please input the number2: 5
    7
    

    十、shell 工具

    10.1 cut

    在文件中负责剪切数据用的。cut命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

    语法:cut [选项参数] filename

    选项参数说明:

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

    案例:

    ①数据准备

    [root@hadoop shell]$ touch cut.txt
    [root@hadoop shell]$ vim cut.txt
    dong,shen
    guan,zhen
    wo,wo
    lai,,lai
    le,,le
    

    ②切割cut.txt第一列

    [root@hadoop100 ~]# cut -d , -f 1 cut.txt 
    dong
    guan
    wo
    lai
    le
    

    ③切割cut.txt第二、三列

    [root@hadoop100 ~]# cut -d , -f 2,3 cut.txt 
    shen
    zhen
    wo
    ,lai
    ,le
    
    

    ④在cut.txt文件中切割出guan

    [root@hadoop100 ~]# cat cut.txt | grep "guan" | cut -d , -f 1
    guan
    

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

    [root@hadoop100 ~]# echo $PATH | cut -d: -f 2-
    /usr/local/bin:/usr/sbin:/usr/bin:/root/bin
    

    ⑥切割ifconfig后打印的IP地址

    [root@hadoop100 ~]# ifconfig eth0
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.182.100  netmask 255.255.255.0  broadcast 192.168.182.255
            ether 00:0c:29:30:c6:e8  txqueuelen 1000  (Ethernet)
            RX packets 5493  bytes 392357 (383.1 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 1556  bytes 158015 (154.3 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    [root@hadoop100 ~]# ifconfig eth0 | grep "inet" | cut -d "i" -f 2 | cut -d " " -f 2
    192.168.182.100
    
    

    10.2 sed

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

    语法: sed [选项参数] ‘command’ filename

    选项参数说明:

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

    命令功能描述:

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

    案例:

    ①数据准备

    [root@hadoop shell]$ vim sed.txt
    dong,shen
    guan,zhen
    wo,wo
    lai,lai
    le,le
    

    ②将mei nv这个单词插入到sed.txt第二行下,打印(此时文件内容并未发生改变)

    [root@hadoop100 ~]# sed '2a mei nv' sed.txt 
    dong,shen
    guan,zhen
    mei nv
    wo,wo
    lai,lai
    le,le
    

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

    [root@hadoop100 ~]# sed '/wo/d' sed.txt 
    dong,shen
    guan,zhen
    lai,lai
    le,le
    

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

    [root@hadoop100 ~]# sed 's/wo/ni/g' sed.txt 
    dong,shen
    guan,zhen
    ni,ni
    lai,lai
    le,le
    

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

    [root@hadoop100 ~]# sed -e '2d' -e 's/wo/ni/g' sed.txt
    dong,shen
    ni,ni
    lai,lai
    le,le
    

    10.3 awk

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

    语法:

    awk [选项参数] ‘pattern1{action1} pattern2{action2}...’ filename
    pattern:表示AWK在数据中查找的内容,就是匹配模式
    action:在找到匹配内容时所执行的一系列命令

    选项参数:

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

    案例:

    10.4 sort

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

    语法:sort(选项)(参数)

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

    案例:

    ①数据准备:

    [root@hadoop shell]$ touch sort.sh
    [root@hadoop shell]$ vim sort.sh 
    bb:40:5.4
    bd:20:4.2
    xz:50:2.3
    cls:10:3.5
    ss:30:1.6
    

    ②按照分割后的第三列倒序排序

    [root@hadoop shell]$ sort -t : -nrk 3  sort.sh 
    bb:40:5.4
    bd:20:4.2
    cls:10:3.5
    xz:50:2.3
    ss:30:1.6
    
    展开全文
  • shell编程

    千次阅读 多人点赞 2019-08-05 21:06:35
    什么是shell编程 高大上的解释,往往让人摸不住头脑。一句话概括就是:shell编程就是对一堆Linux命令的逻辑化处理。 为什么要会shell编程 就是批处理动作,解放双手,避免重复性劳动。 第一个...
    
        
    
    

    全栈工程师开发手册 (作者:栾鹏)
    架构系列文章

    什么是shell编程

    高大上的解释,往往让人摸不住头脑。一句话概括就是:shell编程就是对一堆Linux命令的逻辑化处理。

    为什么要会shell编程

    就是批处理动作,解放双手,避免重复性劳动。

    第一个shell程序

    #!/bin/bash    # 这句话表示用linux指定去解析文本内容
    #第一个shell小程序
    echo hello world!
    

    第一行表示我们选择使用bash shell。shell中#符号表示注释。shell的第一行比较特殊,一般都会以#!开始来指定使用的shell类型。在linux中,除了bash shell以外,还有很多版本的shell, 例如zsh、dash等等…不过bash shell还是我们使用最多的。

    第二行以#符号开始,表示本行是注释,运行的时候是不会运行本行的。

    第三行中的echo是linux中的输出命令,该行的意思很明显的就是输出hello world!

    运行第一个shell程序

    新创建一个文件(hello_world.sh), 然后将以上代码复制到此文件中,然后需要赋予此文件的可执行权限。

    chmod +x hello_world.sh
    

    最后执行:

    ./hello_world.sh
    

    在linux中,后缀名几乎是可以任意的或者没有后缀名,一般将shell保存为xxx.shell是为了看起来更直观。

    如果直接执行hello_world.sh,这时会默认从$PATH环境变量中去寻找,这时,由于我们为将此文件配置在环境变量中,因此会找不到。所以,我们用了"."这个符号,表示从当前目录找。

    除了以上执行方法,我们还可以直接指定shell来运行:

    /bin/sh hello_world.sh
    

    变量

    shell编程中分为两种变量,第一种是我们自己定义的变量(自定义变量),第二种是Linux已定义的环境变量(环境变量, 例如:$PATH, $HOME 等…, 这类变量我们可以直接使用)。

    #!/bin/bash
    #使用环境变量
    echo $PATH
    #自定义变量hello
    hello="hello world"
    echo $hello
    

    以上演示了自定义变量和系统环境变量的用法,使用很简单,就是使用$符号加上变量名就行了。记住:定义变量不用$符号,使用变量要加$就行了。

    在第5行中,我们在自定义变量时,使用了双引号,在shell编程中, 如果变量出现空格或者引号,那么也必须加引号, 否则就可以省略。

    还有一点需要注意,定义变量的时候,“=”左右千万不要有空格啊。

    使用变量

    your_name="qinjx"
    echo $your_name
    echo ${your_name}
    

    变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

    for skill in Ada Coffe Action Java; do
        echo "I am good at ${skill}Script"
    done
    

    将linux命令执行结果赋值给变量

    #!/bin/bash
    path=$(pwd)
    files=`ls -al`
    echo current path: $path
    echo files: $files
    

    以上2行和第3行分别演示了两种方式来将Linux命令执行结果保存到变量。

    第2行将pwd执行结果(当前所在目录)赋值给path变量。

    第3行将ls -al命令执行结果(列出当前目录下所有的文件及文件夹)赋值给变量

    字符串

    字符串可以用单引号,也可以用双引号,也可以不用引号。单双引号的区别跟PHP类似。

    单引号字符串的限制:

    • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
    • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
    your_name="runoob"
    # 使用双引号拼接
    greeting="hello, "$your_name" !"
    greeting_1="hello, ${your_name} !"
    echo $greeting  $greeting_1
    # 使用单引号拼接
    greeting_2='hello, '$your_name' !'
    greeting_3='hello, ${your_name} !'
    echo $greeting_2  $greeting_3
    

    输出结果为:

    hello, runoob ! hello, runoob !
    hello, runoob ! hello, ${your_name} !
    

    获取字符串长度

    string="abcd"
    echo ${#string} #输出 4
    

    提取子字符串

    以下实例从字符串第 2 个字符开始截取 4 个字符:

    string="runoob is a great site"
    echo ${string:1:4} # 输出 unoo
    

    查找子字符串

    查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):

    string="runoob is a great site"
    echo `expr index "$string" io`  # 输出 4
    

    注意: 以上脚本中 ` 是反引号,而不是单引号 ',不要看错了哦。

    Shell 文件接收参数

    echo "执行的文件名:$0";   #  $0 为执行的文件名
    echo "参数个数:$#";    # 传递到脚本的参数个数
    echo "第一个参数为:$1";   # 第1个输入参数
    echo "第二个参数为:$2";   # 第2个输入参数
    
    for i in "$*"; do      # $*以一个单字符串显示所有向脚本传递的参数。$@可以获取所有传入参数
        echo $i
    done
    

    Shell 流程控制

    if-else

    if condition1
    then
        command1
    elif condition2 
    then 
        command2
    else
        commandN
    fi
    

    for 循环

    for var in item1 item2 ... itemN
    do
        command1
        command2
        ...
        commandN
    done
    
    
    或者
    for((i=0;i<20;i++));
    do
       curl 127.0.0.1:9200/_bulk?pretty --data-binary @data/data$i.json
       echo $i成功
    done
    
    
    或者
    for i in $(seq 0 20)
    do
       curl 127.0.0.1:9200/_bulk?pretty --data-binary @data/data$i.json
       echo $i成功
    done
    
    
    
    

    while 语句

    while condition
    do
        command
    done
    

    Shell case语句

    aNum=1
    case aNum in
      1)
        command1
        command2
        commandN
        ;;
      2)
        command1
        command2
        commandN
        ;;
    esac
    

    Shell 数组

    数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似)。

    与大部分编程语言类似,数组元素的下标由0开始。

    在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:

    数组名=(值1 值2 ... 值n)
    
    my_array=(A B "C" D)
    echo "第一个元素为: ${my_array[0]}"
    echo "第二个元素为: ${my_array[1]}"
    echo "第三个元素为: ${my_array[2]}"
    echo "第四个元素为: ${my_array[3]}"
    echo "数组的元素为: ${my_array[*]}"
    echo "数组的元素为: ${my_array[@]}"
    echo "数组元素个数为: ${#my_array[*]}"
    echo "数组元素个数为: ${#my_array[@]}"
    
    还可以单独定义数组的各个分量:
    
    my_array[0]=value0
    

    shell 数组遍历的3种方法

    标准的for循环

    for(( i=0;i<${#array[@]};i++)) do
    #${#array[@]}获取数组长度用于循环
    echo ${array[i]};
    done;
    

    for … in
    遍历(不带数组下标):

    for element in ${array[@]}
    #也可以写成for element in ${array[*]}
    do
    echo $element
    done
    

    遍历(带数组下标):

    for i in "${!arr[@]}";   
    do   
        printf "%s\t%s\n" "$i" "${arr[$i]}"  
    done  
    

    While循环法:

    i=0  
    while [ $i -lt ${#array[@]} ]  
    #当变量(下标)小于数组长度时进入循环体
    do  
        echo ${ array[$i] }  
        #按下标打印数组元素
        let i++  
    done  
    

    算术运算符

    假定变量 a 为 10,变量 b 为 20:

    运算符 说明 举例
    + 加法 `expr $a + $b` 结果为 30。
    - 减法 `expr $a - $b` 结果为 -10。
    * 乘法 `expr $a * $b` 结果为 200。
    / 除法 `expr $b / $a` 结果为 2。
    % 取余 `expr $b % $a` 结果为 0。
    = 赋值 a=$b 将把变量 b 的值赋给 a。
    == 相等。 用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。
    != 不相等。 用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。
    #!/bin/bash
    a=10
    b=20
    
    val=`expr $a + $b`
    echo "a + b : $val"
    
    val=`expr $a - $b`
    echo "a - b : $val"
    
    val=`expr $a \* $b`
    echo "a * b : $val"
    
    val=`expr $b / $a`
    echo "b / a : $val"
    
    val=`expr $b % $a`
    echo "b % a : $val"
    
    if [ $a == $b ]
    then
       echo "a 等于 b"
    fi
    if [ $a != $b ]
    then
       echo "a 不等于 b"
    fi
    

    关系运算符

    关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

    假定变量 a 为 10,变量 b 为 20:

    运算符 说明 举例
    -eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
    -ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
    -gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
    -lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
    -ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
    -le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。
    #!/bin/bash
    a=10
    b=20
    
    if [ $a -eq $b ]
    then
       echo "$a -eq $b : a 等于 b"
    else
       echo "$a -eq $b: a 不等于 b"
    fi
    if [ $a -ne $b ]
    then
       echo "$a -ne $b: a 不等于 b"
    else
       echo "$a -ne $b : a 等于 b"
    fi
    if [ $a -gt $b ]
    then
       echo "$a -gt $b: a 大于 b"
    else
       echo "$a -gt $b: a 不大于 b"
    fi
    if [ $a -lt $b ]
    then
       echo "$a -lt $b: a 小于 b"
    else
       echo "$a -lt $b: a 不小于 b"
    fi
    if [ $a -ge $b ]
    then
       echo "$a -ge $b: a 大于或等于 b"
    else
       echo "$a -ge $b: a 小于 b"
    fi
    if [ $a -le $b ]
    then
       echo "$a -le $b: a 小于或等于 b"
    else
       echo "$a -le $b: a 大于 b"
    fi
    

    布尔运算符

    变量 a 为 10,变量 b 为 20:

    运算符 说明 举例
    ! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
    -o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
    -a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。
    a=10
    b=20
    
    if [ $a != $b ]
    then
       echo "$a != $b : a 不等于 b"
    else
       echo "$a != $b: a 等于 b"
    fi
    if [ $a -lt 100 -a $b -gt 15 ]
    then
       echo "$a 小于 100 且 $b 大于 15 : 返回 true"
    else
       echo "$a 小于 100 且 $b 大于 15 : 返回 false"
    fi
    if [ $a -lt 100 -o $b -gt 100 ]
    then
       echo "$a 小于 100 或 $b 大于 100 : 返回 true"
    else
       echo "$a 小于 100 或 $b 大于 100 : 返回 false"
    fi
    if [ $a -lt 5 -o $b -gt 100 ]
    then
       echo "$a 小于 5 或 $b 大于 100 : 返回 true"
    else
       echo "$a 小于 5 或 $b 大于 100 : 返回 false"
    fi
    

    逻辑运算符

    变量 a 为 10,变量 b 为 20:

    运算符 说明 举例
    && 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
    || 逻辑的 OR [[ $a -lt 100 \|\| $b -gt 100 ]] 返回 true
    a=10
    b=20
    
    if [[ $a -lt 100 && $b -gt 100 ]]
    then
       echo "返回 true"
    else
       echo "返回 false"
    fi
    
    if [[ $a -lt 100 || $b -gt 100 ]]
    then
       echo "返回 true"
    else
       echo "返回 false"
    fi
    

    字符串运算符

    假定变量 a 为 “abc”,变量 b 为 “efg”:

    运算符 说明 举例
    = 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
    != 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
    -z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
    -n 检测字符串长度是否为0,不为0返回 true。 [ -n $a ] 返回 true。
    str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。
    a="abc"
    b="efg"
    
    if [ $a = $b ]
    then
       echo "$a = $b : a 等于 b"
    else
       echo "$a = $b: a 不等于 b"
    fi
    if [ $a != $b ]
    then
       echo "$a != $b : a 不等于 b"
    else
       echo "$a != $b: a 等于 b"
    fi
    if [ -z $a ]
    then
       echo "-z $a : 字符串长度为 0"
    else
       echo "-z $a : 字符串长度不为 0"
    fi
    if [ -n "$a" ]
    then
       echo "-n $a : 字符串长度不为 0"
    else
       echo "-n $a : 字符串长度为 0"
    fi
    if [ $a ]
    then
       echo "$a : 字符串不为空"
    else
       echo "$a : 字符串为空"
    fi
    

    文件测试运算符

    假设file="/var/www/runoob/test.sh"

    运算符 说明 举例
    -b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
    -c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
    -d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
    -f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
    -g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
    -k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
    -p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
    -u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
    -r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
    -w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
    -x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
    -s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
    -e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。

    打印输出

    Shell echo命令

    显示普通字符串

    echo "It is a test"
    echo It is a test         # 双引号完全可以省略
    echo "\"It is a test\""    # 显示转义字符
    
    # 显示变量
    name="luanpeng"
    echo "$name It is a test" 
    
    echo -e "OK! \n" # -e 开启转义
    
    echo -e "OK! \c" # -e 开启转义 \c 打印后不换行
    
    echo "It is a test" > myfile   # 显示结果定向至文件
    
    echo `date`   # 显示命令执行结果
    

    Shell printf 命令

    printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 
    
     %s %c %d %f都是格式替代符
    
    %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
    
    %-4.2f 指格式化为小数,其中.2指保留2位小数。
    

    shell 函数

    funWithParam(){
        echo "第一个参数为 $1 !"
        echo "第二个参数为 $2 !"
        echo "第十个参数为 $10 !"
        echo "第十个参数为 ${10} !"
        echo "第十一个参数为 ${11} !"
        echo "参数总数有 $# 个!"
        echo "作为一个字符串输出所有参数 $* !"
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73
    

    我们可以用函数来测试命令的运行结果

    #!/usr/bin/env bash
    isok(){
    	if [ $1 -eq 0 ]
    		then 
    			echo $2 sucess   # sucess=0
    	else
    			echo $2=============================失败
    	fi
    }
    
    apt-get install vim
    echo $?
    isok $? "apt-get install vim"
    

    Shell 文件引用

    #使用 . 号来引用test1.sh 文件
    . ./test1.sh
    
    # 或者使用以下包含文件代码
    # source ./test1.sh
    

    Shell脚本中调用另外一个脚本的方法

    在Linux平台上开发,经常会在console(控制台)上执行另外一个脚本文件,经常用的方法有:./my.sh 或 source my.sh 或 . my.sh;这三种方法有什么不同呢?我们先来了解一下在一个shell脚本中如何调用另外一个shell脚本,其方法有 fork exec source。

    1、fork ( /directory/script.sh) :

    如果shell中包含执行命令,那么子命令并不影响父级的命令,在子命令执行完后再执行父级命令。子级的环境变量不会影响到父级。

    fork是最普通的, 就是直接在脚本里面用/directory/script.sh来调用script.sh这个脚本. 运行的时候开一个sub-shell执行调用的脚本,sub-shell执行的时候,parent-shell还在。

    sub-shell执行完毕后返回parent-shell. sub-shell从parent-shell继承环境变量.但是sub-shell中的环境变量不会带回parent-shell

    使用时直接在shell文档中写另一个shell脚本的地址就行了。

    /lp/hadoop/hadoop-2.7.3/sbin/start-all.sh
    

    2、exec (exec /directory/script.sh):

    执行子级的命令后,不再执行父级命令。

    exec与fork不同,不需要新开一个sub-shell来执行被调用的脚本. 被调用的脚本与父脚本在同一个shell内执行。但是使用exec调用一个新脚本以后, 父脚本中exec行之后的内容就不会再执行了。这是exec和source的区别

    3、source (source /directory/script.sh):

    执行子级命令后继续执行父级命令,同时子级设置的环境变量会影响到父级的环境变量。

    与fork的区别是不新开一个sub-shell来执行被调用的脚本,而是在同一个shell中执行. 所以被调用的脚本中声明的变量和环境变量, 都可以在主脚本中得到和使用.

    以上三种就是调用shell脚本的不同方法,./my.sh即是fork的方法,source my.sh和. my.sh(点加空格加脚本文件)既是source的方法。

    在linux系统上,搭建嵌入式开发平台,在交叉编译代码之前,都需要执行脚本设置环境变量,切记需要使用sourc 或 点的方式执行shell脚本,原因如上。

    Linux shell 中()() ` `,{},$[] $(()),[ ] (( )) [[ ]]作用与区别

    参考:https://blog.csdn.net/x1269778817/article/details/46535729

    Linux 命令行 &&与||

    参考:https://www.jianshu.com/p/25b0d6c9dc9f

    参考:http://c.biancheng.net/view/735.html

    Linux 下以其他用户身份运行程序—— su、sudo、runuser

    参考:https://www.cnblogs.com/bodhitree/p/6018369.html

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 54,162
精华内容 21,664
关键字:

shell编程