zoukankan      html  css  js  c++  java
  • Shell编程入门

    • shell语法
    • shell变量
    • shell变量表达式
    • shell条件判断语句if、case
    • shell循环控制语句for、while、until
    shell语法
    • 开头
    • 注释
    • 执行命令 例如:使用vi编辑器创建/root/date文件,如下共有三行命令
    1. 创建文件
    [root@localhost ~]# vi /root/date
    
    #!/bin/bash
    #filename:date
    echo "Mr.$USER,Today is:"
    echo $(date)
    echo Whish you a lucky day !
    
    

    2.设置可执行权限

    [root@localhost ~]# chmod u+x /root/date
    

    使用ls命令可以查看/root/date文件具有可执行权限

    [root@localhost ~]# ls -l /root/date
    -rwxr--r--. 1 root root 95 Jul 18 18:25 /root/date
    

    3.输入这个文件的完整路径即可执行Shell程序

    [root@localhost ~]# /root/date
    Mr.root,Today is:
    Thu Jul 18 18:37:48 EDT 2019
    Whish you a lucky day !
    

    4.使用bash命令执行程序(当使用bash执行程序时,就是告诉系统它是一个可执行脚本,不需要设置/root/date的可执行权限也可以执行)

    [root@localhost ~]# chmod u-x /root/date  
    [root@localhost ~]# ls -l /root/date
    -rw-r--r--. 1 root root 95 Jul 18 18:25 /root/date
    [root@localhost ~]# /root/date
    -bash: /root/date: Permission denied
    [root@localhost ~]# bash /root/date
    Mr.root,Today is:
    Thu Jul 18 18:44:42 EDT 2019
    Whish you a lucky day !
    

    Shell变量

    1.常用环境变量

    Shell环境变量描述
    HOME 用于保存用户主目录的完全路径名
    PATH 用于保存用冒号分割的目录路径名,Shell将按PATH变量中给出的顺序搜索这些目录,找到的第一个与命令名称一致的可执行文件将被执行。
    TERM 终端的类型
    UID 当前用户的UID,由数字构成
    PWD 当前工作目录的绝对路径名,该变量的取值随cd命令的使用而变化
    PS1 主提示符,在root用户下,默认得住提示符是“#”,在普通用户下,默认的主提示符是“$”
    PS2 在Shell接收用户输入命令的过程中,如果用户在输入行的末尾输入“”然后按回车键,或者当用户按回车键时Shell判断出用户输入的命令没有结束时,就显示这个辅助提示符,提示用户继续输入命令的其余部分,默认的辅助提示符是“>”

    例如:查看当前用户Shell定义的环境变量的值

    [root@localhost ~]# echo $HOME
    /root
    [root@localhost ~]# echo $PWD
    /root
    [root@localhost ~]# echo $PS1
    [u@h W]$
    [root@localhost ~]# echo $PS2
    >
    [root@localhost ~]# echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
    [root@localhost ~]# echo $TERM
    xterm
    [root@localhost ~]# echo $UID
    0
    

    2.定义用户的变量 语法:变量名=变量值

    注意:定义变量时,变量名前不应该家符合“$”,在引用变量的内容时则应在变量名前加符合“$”.在给变量赋值时,等号两边一定不能留空格,若变量中本身就包含了空格,则整个字符串都要用双引号括起来。在编写Shell程序时,为了使变量名和命令名相区别,建议所有的变量名都用大写字母来表示。

    例如:变量值中包含了空格,需将整个字符串用双引号括起来

    [root@localhost ~]# AA="Hello Linux"
    [root@localhost ~]# echo $AA
    Hello Linux
    
    • readonly 变量名

    在说明一个保留并将它设置为一个特定值后就不再改变它的值时,可以使用readonly命令来保证一个变量的只读性。

    例如:设置变量A为只读

    [root@localhost ~]# A=100
    [root@localhost ~]# readonly A
    [root@localhost ~]# echo $A
    100
    [root@localhost ~]# A=200
    -bash: A: readonly variable
    
    • export 变量名

    在任何时候创建的变量都只是当前Shell的局部变量,所有不能被Shell运行的其他命令或 Shell程序所利用,而export命令可以将一个局部变量提供给Shell命令使用。

    例如:将局部变量B提供给Shell程序使用

    [root@localhost ~]# B=100
    [root@localhost ~]# export B
    [root@localhost ~]# echo $B
    100
    [root@localhost ~]# env|grep B
    B=100
    

    也可以在给变量赋值的同时使用export命令

    • export 变量名=变量值

    例如:使用export设置的变量在Shell以后运行的所有命令或程序中都可以访问到。

    [root@localhost ~]# export C=100
    [root@localhost ~]# echo $C
    100
    [root@localhost ~]# env|grep C
    C=100
    

    3.位置参数变量

    当我们执行一个shell脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量,比如:./myshell.sh 100 200,这个就是一个执行shell的命令行,可以在myshell脚本中获取到 参数信息。

    基本语法功能描述
    $n n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,十以上的参数需要用大括号包含,如$(10)
    $* 代表命令行中所有位置的参数,$*把所有参数看作一个整体
    $@ 代表命令行中所有位置的参数,$@把每个参数区分对待
    $# 代表命令行中所有位置参数的数量

    例如:

    [root@localhost myshell]# sh ./myshell.sh 100 200
    ./myshell.sh,100,200
    100 200
    100 200
    参数的个数=2
    
    
    [root@localhost myshell]# ./myshell.sh 1 2 3 4 5 6 7 8 9 10
    -bash: ./myshell.sh: Permission denied
    [root@localhost myshell]# chmod u+x myshell.sh
    [root@localhost myshell]# ls -l 
    total 4
    -rwxr--r--. 1 root root 97 Jul 19 08:50 myshell.sh
    [root@localhost myshell]# ./myshell.sh 1 2 3 4 5 6 7 8 9 10
    ./myshell.sh,1,2
    1 2 3 4 5 6 7 8 9 10
    1 2 3 4 5 6 7 8 9 10
    参数的个数=10
    

    4.预定义变量

    就是shell设计者事先已经定义好的变量,可以直接在shell脚本中使用,和环境变量类似,所不同的是用户只能根据shell定义来使用这些变量,所有预定义变量都是由符合“$”和另一个符合组成的。

    预定义变量描述
    $$ 当前进程的进程号(PID)
    $! 后台运行的最后一个进程号(PID)
    $? 最后一次执行命令的返回状态,0表示没有错误,非0表示有错误

    5.参数置换的变量

    含义:通常是指将含义一个变量表达式的值赋给另一个变量。也是一种为变量赋值的方式。

    说明:变量1、变量2用var1、var2表示,字符串用sring表示; var:type=value,“:”表示注解,提示变量的类型。var为要定义的变量,type为该变量期待的类型,value为赋给该变量的值。 本质上和var = value是一回事,只是加上了var的类型说明。 类型注解是一种提示,并非强制的。

    格式var1为空var2不为空
    var2=${var1:-string} var2=string var1不变 var2=$var1 var1不变
    var2=${var1:=string} var2=string varvar2=string var1=string var2=$var1 ar1不变
    var2=${var1:+string} var2为空 var1不变(也就是说var1也是空) var2=string var1不变
    var2=${var1:?string} 输出格式:hell脚本名:var1=string 并退出shell var2不变 var2=$var1 var1不变

    所有这形式中的参数既可以是位置参数,也可以是在另一个变量,只是用位置参数的情况比较多。

    变量表达式

    • test是shell程序的一个表达式

    语法:test [表达式]

    字符串比较
    字符串比较符号描述
    = 比较两个字符串是否相同,相同则为“是”
    != 比较两个字符串是否相同,不同则为“是”
    -n 比较字符串的长度是否大于0,如果大于0则是为“是”
    -z 比较字符串的长度是否等于0,如果等于0则为“是”

    例如:字符串比较的使用

    [root@localhost ~]# str1=abcd
    [root@localhost ~]# test $str1=abcd
    [root@localhost ~]# echo $?
    0
    

    结果显示0表示字符串str1确实等于abcd.

    test处理含有空格的变量时最好用引号将变量括起来,否则会出现错误的结果。因为Shell在处理命令行时将会去掉多余的空格,而用引号括起来则可以防止shell去掉这些空格。

    数字比较

    用于测试数字的大小

    数字比较符合描述
    -eq 相等
    -ge 大于等于
    -le 小于等于
    -ne 不等于
    -gt 大于
    -lt 小于

    例如:数字相等比较

    root@localhost ~]# int1=1234
    [root@localhost ~]# int2=01234
    [root@localhost ~]# test $int1 -eq int2
    -bash: test: int2: integer expression expected
    [root@localhost ~]# echo $?
    2
    [root@localhost ~]# test "$int1 -eq int2"
    [root@localhost ~]# echo $?
    0
    

    从上面可以看出,当test处理有空格变量时,不使用引号将变量括起来会导致错误。

    例子:数字大于比较

    [root@localhost ~]# int1=4
    [root@localhost ~]# test “$int1 -gt 2"
    > echo $?
    > exit
    > ^C
    [root@localhost ~]# test "$int1 -gt 2"
    [root@localhost ~]# echo $?
    0
    

    从上图例子可以看出,当引号使用中文格式时会出错。最后结果0表示字符int1的值确实大于2.

    逻辑测试

    用于测试文件是否存在

    逻辑测试符合描述
    ! 与一个逻辑值相反的逻辑值
    -a 两个逻辑值为"是"返回值才为“是”,反之为"否"
    -o 两个逻辑值有一个为“是”返回值就为"是"

    例如:逻辑测试

    [root@localhost ~]# test -r "empty -a -s empty"
    [root@localhost ~]# echo $?
    1
    

    结果显示表示empty存在且只读以及长度为0

    文本操作测试

    用于测试文件的文件操作逻辑

    文件存在测试符合描述
    -d 对象存在且为目录则返回值为“是”
    -f 对象存在且为文件则返回值为“是”
    -L 对象粗壮乃且为符号链接则返回值为“是”
    -r 对象存在且可读则返回值为“是”
    -s 对象存在且长度非0则返回值为“是”
    -w 对象存在且可写则返回值为“是”
    -x 对象存在且可执行则返回值为“是”
    ! 测试条件的否定

    例子:文本操作测试

    [root@localhost ~]# cat /dev/null>empty
    [root@localhost ~]# cat empty
    [root@localhost ~]# test -r empty
    [root@localhost ~]# echo $?
    0
    

    结果显示0表示文件empty存在且只读

    [root@localhost ~]# test ! -s empty
    [root@localhost ~]# echo $?
    0
    

    结果显示0表示文件empty存在且文件长度为0

    Shell条件判读语句

    • if
    • case
    if条件语句

    语法格式:

    • if-then-fi语句

    例如:使用if-then-fi语句创建简单的shell程序( 创建文件名/root/continue,文件名如下)

    [root@localhost ~]# vi /root/continue
    [root@localhost ~]# cat /root/continue
    #!/bin/bash
    #filename:continue
    echo -n "Do you want to continue: Y or N"
    read ANSWER
    if [$ANSWER=N -o $ANSWER=n]
    then
    exit
    fi
    [root@localhost ~]# bash /root/continue
    Do you want to continue: Y or N
    
    • if-then-else-fi语句 例如:使用if-then-else-fi语句创建一个根据输入的分数判断分数是否及格的shell程序 文件名为/root/score,如下:
    [root@localhost ~]# vi /root/score
    [root@localhost ~]# cat /root/score
    #!/bin/bash
    #filename:score
    echo -n "please input a score:"
    read SCORE
    echo "You input Score is $SCORE"
    if [$SCORE -ge 60]
    then
    echo -n "Congratulation!You Pass the examination."
    else
    echo -n "Sorry!You Fall the examination!"
    fi
    echo -n "press any key to continue!"
    read $GOOUT
    

    运行Shell程序/root/score,输出内容如下

    [root@localhost ~]# bash /root/score
    please input a score:80
    You input Score is 80
    /root/score: line 6: [80: command not found
    Sorry!You Fall the examination!press any key to continue!
    [root@localhost ~]# ls -l /root/score
    -rwxr--r--. 1 root root 278 Jul 19 19:26 /root/score
    [root@localhost ~]# vi /root/score
    [root@localhost ~]# bash /root/score
    please input a score:80
    You input Score is 80
    Congratulation!You Pass the examination.press any key to continue!
    

    上例中提示第6行"[80: command not found" 运行出错,经过排查命令运行权限及语句发现。是"["和变量"60"之前缺少空格引起。

    case条件语句

    为用户提供根据字符串或变量的值从多个选项中选择一项的方法。比如,通过计算string的值,将其结果一次与运算式exp-1和exp-2等进行比较,指导找到一个匹配的运算式为止。如果找到匹配项,则执行它下面的命令直到遇到一对分号(;;)为止。在case运算中也可以使用shell通配符(、?、[]).通常用作为case命令的最后运算式,以便在前面找不到任何相应的匹配项时执行"其他命令行"的命令。 例如:使用case语句创建一个菜单选择的shell脚本。文件名为/root/selection,内容如下:

    [root@localhost ~]# vi /root/selection
    [root@localhost ~]# cat /root/selection
    #!/bin/bash
    #filename:selection
    #Display a menu
    echo _
    echo "1 Restore"
    echo "2 Backup"
    echo '3 Unload"
    echo
    #Read and excute the user's selection
    echo -n "Enter Choice:"
    read CHOICE
    case "$CHOICE" in
    1) echo "Restore";;
    2) echo "Backup";;
    3) echo "Unload";;
    *) echo "Sorry $CHOICE is not a valid choice
    exit 1
    esac
    [root@localhost ~]# bash /root/selection
    _
    1 Restore
    2 Backup
    3 Unload"
    echo
    #Read and excute the users selection
    Enter Choice

    Shell循环控制语句

    • for
    • while
    • ntil
    for循环语句

    for循环语句对一个变量的可能的值都执行一个命令序列。赋给变量的几个数值可以在程序中以数值列表的形式提供,也可以在程序以外以位置参数的形式提供。

    变量名可以是用户选择的任何字符串,如果变量名是var,则在in之后给出的数字将按顺序替换循环命令列表的"$var".如果省略了in,则变量var的取值将是位置参数。对变量的每一个可能的赋值都将执行do和done之间的命令列表。

    例如:使用for语句创建简单shell程序,文件名/root/for,如下

    [root@localhost ~]# vi /root/for
    [root@localhost ~]# cat /root/for
    #!/bin/bash
    #filename:for
    for ab in 1 2 3 4
    do
    echo $ab
    done
    

    运行程序/root/for,输出内容如下:

    [root@localhost ~]# bash /root/for
    1
    2
    3
    4
    

    例子:使用for语句创建求命令行上所有整数之和的shell程序,文件名是/root/sum,如下

    [root@localhost ~]# vi /root/sum
    [root@localhost ~]# cat /root/sum
    #!/bin/bash
    #filename:sum
    sum=0
    for INT in $*
    do
    sum=$(expr $sum + $INT)
    done
    echo $sum
    [root@localhost ~]# bash /root/sum 1 2 3 4 5
    15
    
    while循环语句

    while语句是用命令的返回状态值来控制循环的。只要while的“若干个命令行1”中最后一个命令的返回状态为真,while循环就继续执行“若干个命令行2” 例子:使用while语句创建一个计算1~5的平方的shell程序,文件名是/root/zx,如下

    [root@localhost ~]# vi /root/zx
    [root@localhost ~]# cat /root/zx
    #!/bin/bash
    #filename:zx
    int=1
    while [ $int -le 5 ]
    do
    sq=$(expr $int * $int)
    echo $sq
    int=$(expr $int + 1)
    done
    echo "Job Completed"
    [root@localhost ~]# bash /root/zx
    1
    4
    9
    16
    25
    Job Completed
    

    例子:使用while语句创建一个工具输入的数值求累加和(1+2+3+4....+n)的shell程序,文件名/root/number,如下

    [root@localhost ~]# vi /root/number
    [root@localhost ~]# cat /root/number
    #!/bin/bash
    #filename:number
    echo -n "Please Input Number:"
    read NUM
    number=0
    sum=0
    while [ $number -le $NUM ]
    do
    echo number
    echo "$number"
    number=$(expr $number + 1)
    echo sum
    echo "$sum"
    sum=$(expr $sum + $number)
    done
    echo
    
    [root@localhost ~]# bash /root/number
    Please Input Number:4
    number
    0
    sum
    0
    number
    1
    sum
    1
    number
    2
    sum
    3
    number
    3
    sum
    6
    number
    4
    sum
    10
    
    until循环语句

    它和while类似。是另外一种循环结构,两者区别在于:while循环语句在条件为真时继续执行循环,二until循环语句则是在条件为假时继续执行循环。 例子:使用until语句创建一个输入exit退出的shell程序,文件名/root/hk,如下

    [root@localhost ~]# vi /root/hk
    [root@localhost ~]# cat /root/hk
    #!/bin/bash
    #filename:hk
    echo "This example is for test until .... do "
    echo "If you input [exit] then quit the system "
    echo -n "please input:"
    read EXIT
    until [ $EXIT = "exit" ]
    do
    read EXIT
    done
    echo "OK!"
    [root@localhost ~]# bash /root/hk
    This example is for test until .... do 
    If you input [exit] then quit the system 
    please input:
    

    特别注意:编辑命令时,双引号是英文状态下输入的双引号,如果中文状态下输入的双引号,会导致命令出错无法执行。

    摘自:《Linux实用教程》人民邮电出版社出版发行 於岳编著

  • 相关阅读:
    c语言中 fgetc函数、fputc函数实现文件的复制
    c语言 13-7 利用fgetc函数输出文件的字符数
    c语言 13-6 利用fgetc函数输出文件的行数
    c语言中fgetc函数:显示文件内容
    c语言 13-5
    c语言 获取程序上一次运行时间的程序
    hzwer模拟赛 虫洞
    LYDSY热身赛 escape
    bzoj2330 糖果
    繁华模拟赛 Vicent坐电梯
  • 原文地址:https://www.cnblogs.com/mylive/p/11216189.html
Copyright © 2011-2022 走看看