Shell编程

Linux Shell编程 ​ Shell是一个命令行解释器程序规范,他接受应用程序/用户命令,然后调用操作系统内核完成相关的功能。它是用户使用 Linux 的桥梁。简单来说Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。也可以这样认为,linux中的shell就是linux内核的一个外层保护工具,并负责完成用户与内核之间的交互​ Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。 阅读详情
【1】Shell简介
    Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。
    它虽然不是Unix/Linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Unix/Linux系统的关键。

    Shell有两种执行命令的方式:
    交互式(Interactive):解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。
    批处理(Batch):用户事先写一个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。

【2】几种常见的Shell
    Unix/Linux上常见的Shell脚本解释器有bash、sh、csh、ksh等,习惯上把它们称作一种Shell。我们常说有多少种Shell,其实说的是Shell脚本解释器。
    【bash】
    bash是Linux标准默认的shell,本教程也基于bash讲解。bash由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的缩写,内部命令一共有40个。
    【sh】
    sh 由Steve Bourne开发,是Bourne Shell的缩写,sh 是Unix 标准默认的shell。
    【ash】
    ash shell 是由Kenneth Almquist编写的,Linux中占用系统资源最少的一个小shell,它只包含24个内部命令,因而使用起来很不方便。
    【csh】
csh 是Linux比较大的内核,它由以William Joy为代表的共计47位作者编成,共有52个内部命令。该shell其实是指向/bin/tcsh这样的一个shell,也就是说,csh其实就是tcsh。
    【ksh】
    ksh 是Korn shell的缩写,由Eric Gisin编写,共有42条内部命令。该shell最大的优点是几乎和商业发行版的ksh完全兼容,这样就可以在不用花钱购买商业版本的情况下尝试商业版本的性能了。

【3】Shell与编译型语言的差异
    【编译型语言】
    很多传统的程序设计语言,例如Fortran、Ada、Pascal、C、C++和Java,都是编译型语言。这类语言需要预先将我们写好的源代码(source code)转换成目标代码(object code),这个过程被称作“编译”。
    【解释型语言】
    解释型语言也被称作“脚本语言”。执行这类程序时,解释器(interpreter)需要读取我们编写的源代码(source code),并将其转换成目标代码(object code),再由计算机运行。因为每次执行程序都多了编译的过程,因此效率有所下降。
    使用脚本编程语言的好处是,它们多半运行在比编译型语言还高的层级,能够轻易处理文件与目录之类的对象;缺点是它们的效率通常不如编译型语言。不过权衡之下,通常使用脚本编程还是值得的:花一个小时写成的简单脚本,同样的功能用C或C++来编写实现,可能需要两天,而且一般来说,脚本执行的速度已经够快了,快到足以让人忽略它性能上的问题。脚本编程语言的例子有awk、Perl、Python、Ruby与Shell。

【4】什么时候使用Shell
    因为Shell似乎是各UNIX系统之间通用的功能,并且经过了POSIX的标准化。因此,Shell脚本只要“用心写”一次,即可应用到很多系统上。因此,之所以要使用Shell脚本是基于:
    简单性:Shell是一个高级语言;通过它,你可以简洁地表达复杂的操作。
    可移植性:使用POSIX所定义的功能,可以做到脚本无须修改就可在不同的系统上执行。
    开发容易:可以在短时间内完成一个功能强大又妤用的脚本。

【5】第一个Shell脚本  

#!/bin/bash
echo "Hello World !"

    【作为可执行程序】
    将上面的代码保存为test.sh,并 cd 到相应目录:
    chmod +x ./test.sh  #使脚本具有执行权限
    ./test.sh  #执行脚本
    【作为解释器参数】
    这种运行方式是,直接运行解释器,其参数就是shell脚本的文件名,如:
    /bin/sh test.sh
    /bin/php test.php   
    #!/bin/bash
    # Author : mozhiyan
    # Copyright (c) http://see.xidian.edu.cn/cpp/linux/
    # Script follows here:
    echo "What is your name?"
    read PERSON
    echo "Hello, $PERSON"

【6】Shell变量
    【定义变量】
    定义变量时,变量名不加美元符号($),如:
    variableName="value"
    变量名的命名须遵循如下规则:
        首个字符必须为字母(a-z,A-Z)。
        中间不能有空格,可以使用下划线(_)。
        不能使用标点符号。
        不能使用bash里的关键字(可用help命令查看保留关键字)。

    【使用变量】
    使用一个定义过的变量,只要在变量名前面加美元符号($)即可,如:
    your_name="mozhiyan"
    echo $your_name
    echo ${your_name}
    变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:   
    for skill in Ada Coffe Action Java
    do
        echo "I am good at ${skill}Script"
    done
    推荐给所有变量加上花括号,这是个好的编程习惯。
    
    【重新定义变量】
    已定义的变量,可以被重新定义,如:   
    myUrl="http://see.xidian.edu.cn/cpp/linux/"
    echo ${myUrl}
    myUrl="http://see.xidian.edu.cn/cpp/shell/"
    echo ${myUrl}
    【只读变量】
    使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
    下面的例子尝试更改只读变量,结果报错:
    #!/bin/bash
    myUrl="http://see.xidian.edu.cn/cpp/shell/"
    readonly myUrl
    myUrl="http://see.xidian.edu.cn/cpp/danpianji/"
    运行脚本,结果如下:/bin/sh: NAME: This variable is read only.
    
    【变量类型】
    运行shell时,会同时存在三种变量:
    1) 局部变量
    局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
    2) 环境变量
    所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
    3) shell变量
    shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
    
【7】Shell特殊变量
    $0     当前脚本的文件名
    $n     传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
    $#     传递给脚本或函数的参数个数。
    $*     传递给脚本或函数的所有参数。
    $@     传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。
    $?     上个命令的退出状态,或函数的返回值。
    $$     当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。  
    #!/bin/bash
    echo "File Name: $0"
    echo "First Parameter : $1"
    echo "First Parameter : $2"
    echo "Quoted Values: $@"
    echo "Quoted Values: $*"
    echo "Total Number of Parameters : $#"

    【$*与$@的区别】
    #!/bin/bash
    echo "print each param from \"\$*\""
    for var in "$*"
    do
        echo "$var"
    done
    echo "print each param from \"\$@\""
    for var in "$@"
    do
        echo "$var"
    done    
    上面的代码,$*输出参数的整体,$@分别输出每一个参数。
    
    
【8】shell替换
    如果表达式中包含特殊字符,Shell 将会进行替换。例如,在双引号中使用变量就是一种替换,转义字符也是一种替换。
    #!/bin/bash
    a=10
    echo -e "Value of a is $a \n"   
    运行结果:Value of a is 10
    
    转义字符     含义
    \\     反斜杠
    \a     警报,响铃
    \b     退格(删除键)
    \f     换页(FF),将当前位置移到下页开头
    \n     换行
    \r     回车
    \t     水平制表符(tab键)
    \v     垂直制表符
    可以使用 echo 命令的 -E 选项禁止转义,默认也是不转义的;使用 -n 选项可以禁止插入换行符。
    
    【命令替换】`command`
    #!/bin/bash
    DATE=`date`
    echo "Date is $DATE"
    USERS=`who | wc -l`
    echo "Logged in user are $USERS"
    UP=`date ; uptime`
    echo "Uptime is $UP"
    运行结果:
    Date is Thu Jul  2 03:59:57 MST 2009
    Logged in user are 1
    Uptime is Thu Jul  2 03:59:57 MST 2009
    03:59:57 up 20 days, 14:03,  1 user,  load avg: 0.13, 0.07, 0.15
    
    【变量替换】
    ${var}                 变量本来的值
    ${var:-word}         如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。
    ${var:=word}         如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。
    ${var:?message}     如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。若此替换出现在Shell脚本中,那么脚本将停止运行。
    ${var:+word}         如果变量 var 被定义,那么返回 word,但不改变 var 的值。
        #!/bin/bash
        echo ${var:-"Variable is not set"}
        echo "1 - Value of var is ${var}"
        echo ${var:="Variable is not set"}
        echo "2 - Value of var is ${var}"
        unset var
        echo ${var:+"This is default value"}
        echo "3 - Value of var is $var"
        var="Prefix"
        echo ${var:+"This is default value"}
        echo "4 - Value of var is $var"
        echo ${var:?"Print this message"}
        echo "5 - Value of var is ${var}"

【9】Shell运算符
    Bash 支持很多运算符,包括算数运算符、关系运算符、布尔运算符、字符串运算符和文件测试运算符。
    原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
    expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
    #!/bin/bash
    val=`expr 2 \* 2`     #等价于var=$[2*2]
    echo "Total value : $val"
    注意:表达式和运算符之间要有空格。
    运行脚本输出:Total value : 4
    
    【算术运算符】
    #!/bin/sh
    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 is equal to b"
    fi
    if [ $a != $b ]
    then
       echo "a is not equal to b"
    fi
    运行结果:
    a + b : 30
    a - b : -10
    a * b : 200
    b / a : 2
    b % a : 0
    a is not equal to b
    注意:
    乘号(*)前边必须加反斜杠(\)才能实现乘法运算;
    条件表达式要放在方括号之间,并且要有空格,例如 [$a==$b] 是错误的,必须写成 [ $a == $b ]。
    
    【关系运算符】
    a=10,b=20
    -eq     检测两个数是否相等,相等返回 true。                     [ $a -eq $b ] 返回 true。
    -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。
    
    【布尔运算符】
    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="abc",b="efg"
    =         检测两个字符串是否相等,相等返回 true。         [ $a = $b ] 返回 false。
    !=         检测两个字符串是否相等,不相等返回 true。     [ $a != $b ] 返回 true。
    -z         检测字符串长度是否为0,为0返回 true。         [ -z $a ] 返回 false。
    -n         检测字符串长度是否为0,不为0返回 true。         [ -z $a ] 返回 true。
    str     检测字符串是否为空,不为空返回 true。         [ $a ] 返回 true。
    
    【文件测试运算符】
    file="/var/www/tutorialspoint/unix/test.sh"
    -b file     检测文件是否是块设备文件,如果是,则返回 true。     [ -b $file ] 返回 false。
    -c file     检测文件是否是字符设备文件,如果是,则返回 true。     [ -b $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。
    
【10】Shell注释
    以“#”开头的行就是注释,会被解释器忽略。
    sh里没有多行注释,只能每一行加一个#号。
    如果在开发过程中,遇到大段的代码需要临时注释起来,过一会儿又取消注释,怎么办呢?每一行加个#符号太费力了,可以把这一段要注释的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释一样的效果。

【11】Shell字符串
    字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。单双引号的区别跟PHP类似。
    单引号字符串的限制:
        单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
        单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
    双引号的优点:
        双引号里可以有变量
        双引号里可以出现转义字符
    
    【拼接字符串】
    your_name="qinjx"
    greeting="hello,"$your_name"!"
    greeting_1="hello, ${your_name} !"
    echo $greeting $greeting_1
   
    【获取字符串长度】
    string="abcd"
    echo ${#string}          #输出 4
   
    【提取子字符串】
    string="alibaba is a great company"
    echo ${string:1:4}       #输出liba
   
    【查找子字符串】
    string="alibaba is a great company"
    echo `expr index $string is`
   
【12】Shell数组
    Shell在编程方面比Windows批处理强大很多,无论是在循环、运算。
    bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。
    定义数组的一般形式为:array_name=(value0 value1 value2 value3)
    或者
        array_name=(
        value0
        value1
        value2
        value3
        )
    还可以单独定义数组的各个分量:
        array_name[0]=value0
        array_name[1]=value1
        array_name[2]=value2
    可以不使用连续的下标,而且下标的范围没有限制。
    
    【读取数组】
    读取数组元素值的一般格式是:${array_name[index]}
    使用@ 或 * 可以获取数组中的所有元素,例如:
        ${array_name[*]}
        ${array_name[@]}
    
    【获取数组的长度】
    获取数组长度的方法与获取字符串长度的方法相同,例如:
        # 取得数组元素的个数
        length=${#array_name[@]}
        # 或者
        length=${#array_name[*]}
        # 取得数组单个元素的长度
        lengthn=${#array_name[n]}
 
【12】Shell echo指令

【13】Shell printf指令
    printf 命令用于格式化输出, 是echo命令的增强版。它是C语言printf()库函数的一个有限的变形,并且在语法上有些不同。
    注意:printf 由 POSIX 标准所定义,移植性要比 echo 好。
    如同 echo 命令,printf 命令也可以输出简单的字符串:printf "Hello, Shell\n"
    printf 命令的语法:printf  format-string  [arguments...]
        printf "%d %s\n" 1 "abc"    #1 abc
        printf '%d %s\n' 1 "abc"    #1 abc
        printf %s abcdef            #abcdef
        printf %s abc def           #abcdef
        printf "%s\n" abc def       #abc(换行)def
    注意:如果以 %d 的格式来显示字符串,那么会有警告,提示无效的数字,此时默认置为 0;
    如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
    
    根据POSIX标准,浮点格式%e、%E、%f、%g与%G是“不需要被支持”。这是因为awk支持浮点预算,且有它自己的printf语句。这样Shell程序中需要将浮点数值进行格式化的打印时,可使用小型的awk程序实现。然而,内建于bash、ksh93和zsh中的printf命令都支持浮点格式。

【14】Shell if else语句
    if 语句通过关系运算符判断表达式的真假来决定执行哪个分支。Shell 有三种 if ... else 语句:
        if ... fi 语句;
        if ... else ... fi 语句;
        if ... elif ... else ... fi 语句。
    
    if ... else 语句也可以写成一行,以命令的方式来运行,像这样:
        if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;
    注意:条件表达式要放在方括号之间,并且要有空格,例如 [$a==$b] 是错误的,必须写成 [ $a == $b ]。    
    #!/bin/sh
    a=10
    b=20
    if [ $a == $b ]
    then
       echo "a is equal to b"
    elif [ $a -gt $b ]
    then
       echo "a is greater than b"
    elif [ $a -lt $b ]
    then
       echo "a is less than b"
    else
       echo "None of the condition met"
    fi

【15】Shell test命令
    Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
    【数值测试】
    num1=100
    num2=100
    if test $[num1] -eq $[num2]
    then
        echo 'The two numbers are equal!'
    else
        echo 'The two numbers are not equal!'
    fi
   
    【字符串测试】
    num1=100
    num2=100
    if test num1=num2
    then
        echo 'The two strings are equal!'
    else
        echo 'The two strings are not equal!'
    fi
   
    【文件测试】
    cd /bin
    if test -e ./bash
    then
        echo 'The file already exists!'
    else
        echo 'The file does not exists!'
    fi    
    另外,Shell还提供了与( ! )、或( -o )、非( -a )三个逻辑操作符用于将测试条件连接起来,其优先级为:“!”最高,“-a”次之,“-o”最低。

【16】Shell case esac语句
    case ... esac 与其他语言中的 switch ... case 语句类似,是一种多分枝选择结构。
    case 语句匹配一个值或一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:
            case 值 in
            模式1)
                command1
                command2
                command3
                ;;
            模式2)
                command1
                command2
                command3
                ;;
            *)
                command1
                command2
                command3
                ;;
            esac
    
    例如:
        echo 'Input a number between 1 to 4'
        echo 'Your number is:\c'
        read aNum
        case $aNum in
            1)  echo 'You select 1'
            ;;
            2)  echo 'You select 2'
            ;;
            3)  echo 'You select 3'
            ;;
            4)  echo 'You select 4'
            ;;
            *)  echo 'You do not select a number between 1 to 4'
            ;;
        esac
    再如:
            #!/bin/bash
            option="${1}"
            case ${option} in
               -f) FILE="${2}"
                  echo "File name is $FILE"
                  ;;
               -d) DIR="${2}"
                  echo "Dir name is $DIR"
                  ;;
               *)
                  echo "`basename ${0}`:usage: [-f file] | [-d directory]"
                  exit 1 # Command to come out of the program with status 1
                  ;;
            esac



【17】Shell for循环
    for循环一般格式为:
        for 变量 in 列表
        do
            command1
            command2
            ...
            commandN
        done
    例如:
        for loop in 1 2 3 4 5
        do
            echo "The value is: $loop"
        done
    再如:
 
        #!/bin/bash
        for FILE in $HOME/.bash*
        do
           echo $FILE
        done
  
【18】Shell while循环
    while循环例子如下:
        COUNTER=0
        while [ $COUNTER -lt 5 ]
        do
            COUNTER=`expr $COUNTER+1`
            echo $COUNTER
        done
   
    while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按<Ctrl-D>结束循环。
        echo 'type <CTRL-D> to terminate'
        echo -n 'enter your most liked film: '
        while read FILM
        do
            echo "Yeah! great film the $FILM"
        done

【19】Shell until循环
    until循环例子如下:
        #!/bin/bash
        a=0
        until [ ! $a -lt 10 ]
        do
           echo $a
           a=`expr $a + 1`
        done

【20】Shell break和continue命令
    在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,像大多数编程语言一样,Shell也使用 break 和 continue 来跳出循环。
    【break命令】
    例如:
        #!/bin/bash
        while :
        do
            echo -n "Input a number between 1 to 5: "
            read aNum
            case $aNum in
                1|2|3|4|5) echo "Your number is $aNum!"
                ;;
                *) echo "You do not select a number between 1 to 5, game is over!"
                    break
                ;;
            esac
        done
   
    在嵌套循环中,break 命令后面还可以跟一个整数,表示跳出第几层循环。例如:break n
    例如:
        #!/bin/bash
        for var1 in 1 2 3
        do
           for var2 in 0 5
           do
              if [ $var1 -eq 2 -a $var2 -eq 0 ]
              then
                 break 2    #break 2 表示直接跳出外层循环,程序结束
              else
                 echo "$var1 $var2"
              fi
           done
        done
   
     【continue命令】
    continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
    在嵌套循环中,continue 命令后面也可以跟一个整数。例如:continue n

【21】Shell函数
    函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高。像其他编程语言一样,Shell 也支持函数。Shell 函数必须先定义后使用。
    Shell 函数的定义格式如下:
        function_name () {
            list of commands
            [ return value ]
        }
    如果你愿意,也可以在函数名前加上关键字 function:
        function function_name () {
            list of commands
            [ return value ]
        }
    
    例如:
        #!/bin/bash
        funWithReturn(){
            echo "The function is to get the sum of two numbers..."
            echo -n "Input first number: "
            read aNum
            echo -n "Input another number: "
            read anotherNum
            echo "The two numbers are $aNum and $anotherNum !"
            return $(($aNum+$anotherNum))
        }
        funWithReturn
        # Capture value returnd by last command
        ret=$?
        echo "The sum of two numbers is $ret !"
   
    像删除变量一样,删除函数也可以使用 unset 命令,不过要加上 .f 选项,如下所示:    
        $unset .f function_name
    如果你希望直接从终端调用函数,可以将函数定义在主目录下的 .profile 文件,这样每次登录后,在命令提示符后面输入函数名字就可以立即调用。
    
【22】Shell函数参数
    在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...
    例如:
        #!/bin/bash
        funWithParam(){
            echo "The value of the first parameter is $1 !"
            echo "The value of the second parameter is $2 !"
            echo "The value of the tenth parameter is $10 !"
            echo "The value of the tenth parameter is ${10} !"
            echo "The value of the eleventh parameter is ${11} !"
            echo "The amount of the parameters is $# !"  # 参数个数
            echo "The string of the parameters is $* !"  # 传递给函数的所有参数
        }
        funWithParam 1 2 3 4 5 6 7 8 9 34 73
    运行脚本:
        The value of the first parameter is 1 !
        The value of the second parameter is 2 !
        The value of the tenth parameter is 10 !
        The value of the tenth parameter is 34 !
        The value of the eleventh parameter is 73 !
        The amount of the parameters is 12 !
        The string of the parameters is 1 2 3 4 5 6 7 8 9 34 73 !"
    注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
    
【23】Shell输入输出重定向
    Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示。一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器。
    【输出重定向】
    命令输出重定向的语法为:$ command > file
    输出重定向会覆盖文件内容,如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾。
    
    【输入重定向】
    和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:command < file
    例如,计算 users 文件中的行数,可以使用下面的命令:
        wc -l users    #输出2 users
    也可以将输入重定向到 users 文件:
        wc -l < users  #输出2
    注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。
    
    如果希望 stderr 重定向到 file,可以这样写:
        command 2 > file
    如果希望 stderr 追加到 file 文件末尾,可以这样写:
        command 2 >> file
    如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:
        $command > file 2>&1
    或
        $command >> file 2>&1
    
    command > file         将输出重定向到 file。
    command < file         将输入重定向到 file。
    command >> file     将输出以追加的方式重定向到 file。
    n > file             将文件描述符为 n 的文件重定向到 file。
    n >> file             将文件描述符为 n 的文件以追加的方式重定向到 file。
    n >& m                 将输出文件 m 和 n 合并。
    n <& m                 将输入文件 m 和 n 合并。
    << tag                 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
    
    【Here Document】
    Here Document 目前没有统一的翻译,这里暂译为”嵌入文档“。Here Document 是 Shell 中的一种特殊的重定向方式,它的基本的形式如下:
        command << delimiter
            document
        delimiter
    它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
    注意:
        结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
        开始的delimiter前后的空格会被忽略掉。

    例如,通过 wc -l 命令计算 document 的行数:
    wc -l << EOF
        This is a simple lookup program
        for good (and bad) restaurants
        in Cape Town.
    EOF
    #输出3
    
    /dev/null 文件
    如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
        command > /dev/null
    /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到”禁止输出“的效果。    
    
【24】Shell文件包含
    像其他语言一样(C语言的#include,java语言的import),Shell 也可以包含外部脚本,将外部脚本的内容合并到当前脚本。
    Shell 中包含脚本可以使用:
        . filename
    或
        source filename
    两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格。

Unity 升级引擎版本后构建报错:script class layout is incompatible between the editor and the player Unity升级引擎版本后,项目报错:script class layout is incompatible between the editor and the player。 阅读详情

相关推荐

DSP28335新手避坑指南:手把手教你用CCS6.2生成10KHz SPWM(附完整工程)

本文详细介绍了如何使用DSP28335开发板和CCS6.2环境生成10KHz SPWM波形的完整工程指南。从开发环境配置、ePWM模块设置到SPWM算法实现,特别针对新手常见问题提供了解决方案和调试技巧,帮助工程师快速掌握DSP28335的SPWM生成技术。

weixin_42522374的博客 182

《Linux》day4--shell语法(下)

bash中的函数类似于C++中的函数,但是return的返回值与C++不同,返回的是 exit code(退出状态,0表示正常退出,取值为0-255)如果想要获取函数的输出结果,可以通过 echo 输出到sdout 中,然后通过 $(function_name) 来获取sdout中的结果。exit命令可以接受一个整数值作为参数,代表退出状态,如果不指定,默认退出状态是0。在函数内,$1 表示第一个输入的参数,$2 表示第二个输入参数,…注意:函数内的 $0 仍然是文件名,而不是函数名。

qq_59702185的博客 812

华为2288H-V5服务器做raid的详细步骤

操作步骤 服务器启动界面 按del键进入设置输入密码,2288H-v5默认密码是Admin@9000 移动光标选择device manager 驱动管理选择configurationutility 配置管理 选择main menu 主菜单 选择第一个 configuration management 配置管理 选择create virtual driver 创建虚拟驱动选择select RAID level 选择RAID等级选择level-5 选择select drivers 选择驱......

weixin_46041124的博客 1万+

shell 练习题集合(思路和解答)

##########################################################################################部分题目引用自:https://www.centos.bz/2012/07/shell-script-exercises/Q1题目:分析图片服务日志,把日志(每个图片访问次数*图片大小的总和)排行,...

weixin_34397291的博客 251

Pytorch.nn.Linear 解析(数学角度)

pytorch.nn.Linear 是一个类,下面是它的一些初始化参数 in_features : 输入样本的张量大小 out_features : 输出样本的张量大小 bias : 偏置 它主要是对输入数据做一个线性变换。 y=xAT+b y=xA^T+b y=xAT+b 这里A是权重矩阵,b是偏置。他们都是根据 in_features 生成 测试代码: m = torch.nn.Linea...

Medlen 1万+

Android 集成Chrome 浏览器内核 Crosswalk

Crosswalk 内核的兴起与消亡 Android 4.4 版本之前,使用的是基于 androidWebKit 的 WebView 但实际上,由于 Android 的碎片化问题(大量存在不同的 Android 系统版本,并且各个厂商对内置应用进行定制化,有可能用的不是最新的浏览器内核)。这就导致 WebView 在真实环境中对 API 的支持根本无迹可寻,越发混乱。 随着混合开发的兴起,前端对 ...

司马懿的西山居 2万+

linux shell脚本案例一

1.编写shell脚本内容: bsh1.sh文件 #!/bin/bash echo "hello,ljf" echo "what is your name?" read p echo "my name is ${p}" 2.执行脚本 chmod +x ./bsh1.sh sh ./bsh1.sh 或者 ./bsh1.sh 3.执行结果: [jurf@ljf-cento

健康平安的活着的专栏 411

使用 Simulink 进行电力电子系统的小信号模型仿真

电力电子系统(Power Electronics System)包括各种功率转换器(如 DC-DC 转换器、逆变器等)。这些设备中的关键组件(如 MOSFET、IGBT、电容器、电感器等)不仅影响系统的性能,还直接关系到系统的稳定性、效率和可靠性。因此,在设计阶段进行详细的建模和仿真至关重要。小信号模型仿真的目的是通过线性化非线性系统来评估其动态特性,包括增益、相位裕度、带宽等指标。通过本教程,我们介绍了如何使用 Simulink 进行电力电子系统的小信号模型仿真。背景介绍。

xiaoheshang_123的博客 480

shell编程

什么是shell编程 高大上的解释,往往让人摸不住头脑。一句话概括就是:shell编程就是对一堆Linux命令的逻辑化处理。 为什么要会shell编程 就是批处理动作,解放双手,避免重复性劳动。 第一个shell程序 #!/bin/bash #第一个shell小程序 echo hello world! 第一行表示我们选择使用bash shell。shell中#符号表示注释。...

1万+

Python进阶005:修改Jupyter Notebook的工作路径

1、Jupyter Notebook简介 2、修改Jupyter Notebook的工作路径 如下三个步骤: 一、安装notebook 在CMD命令行中输入: pip install notebook 二、启动notebook jupyter notebook 启动后发现是在你的用户目录下,如下图所示,但是该目录下有很多的其他文件或文件夹,因此我想把这个环境切换到我单门创建的一个文件夹中。 三、创建notebook的配置文件 在CMD命令行中执行: jupyter notebook --genera

若北辰 1384

【手把手教学】YOLOv13的Dilated Reparam Block (DRB) 实现细节与优化技巧

DRB(Dilated Reparam Block)是一种创新的卷积神经网络模块,通过多分支膨胀卷积和结构重参数化技术显著提升模型性能。训练阶段使用不同膨胀率和卷积核大小的并行分支增强特征提取能力,推理阶段则将这些分支融合为单一高效的大核卷积。该方法成功解决了大核卷积的计算复杂度和训练困难等问题,在保持推理效率的同时,使模型准确率提升8.56%,mAP暴涨12.33%。DRB的核心在于训练时复杂、推理时简单的设计哲学,以及膨胀卷积的多尺度特征提取能力,为CNN性能优化提供了新的思路。

FJN110的博客 556

SHELL编程——初识SHELL编程

一、什么是SHELL编程? Shell是操作系统的最外层,Shell可以合并编程语言以控制进程和文件,以及启动和控制其他程序。Shell通过提示您输入,向操作系统解释该输出,然后处理来自操作系统的任何结果输出来管理您与操作系统之间的交互。 简单来说,Shell就是一个用户跟操作系统之间的一个命令解释器。Shell是用户与Linux操作系统之间沟通的桥梁,用户可以输入命令执行,又可以利用Shell脚本编程去运行。 二、常见Shell Linux Shell种类非常多,常见的有:Bourne Shell

xcxhzjl的博客 1373

chembl_webresource_client 包数据接口下载chembl数据库;ZINC数据库下载、simles获取

点击进去https://zinc.docking.org/subclasses/kinase/predictions/,然后下载sdf模式,这里可以转化simles格式,如果下载csv里面没有包含simles。参考:https://github.com/chembl/chembl_webresource_client/blob/master/demo_wrc.ipynb。参考:https://zinc.docking.org/这是网页搜索查看,16条数据。这个数据这下载特别慢。

weixin_42357472的博客 3046

Shell编程入门

文章目录Shell 编程入门走进 Shell 编程的大门为什么要学Shell?什么是 Shell?Shell 编程的 Hello WorldShell 变量Shell 编程中的变量介绍Shell 字符串入门Shell 字符串常见操作Shell 数组Shell 基本运算符算数运算符关系运算符逻辑运算符布尔运算符字符串运算符文件相关运算符shell流程控制if 条件语句for 循环语句while 语句shell 函数不带参数没有返回值的函数有返回值的函数带参数的函数 Shell 编程入门 走进 Shell 编程

qq_38106680的博客 725

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Shell编程总结

1.Shell编程简介 Shell是操作系统的最外层,Shell可以合并编程语言以控制进程和文件,以及启动和控制其它程序。Shell通过提示您输入,向内核解释该输入,然后处理来自内核的任何结果输出。 简单来说Shell就是一个用户跟操作系统之间的一个命令解释器。 Linux Shell种类非常多,常见的SHELL如下: Bourne Shell(/usr/bin/sh或...

dengyu7227的专栏 288

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Shell编程简介

Shell在计算机科学中是指为使用者提供操作界面的软件,即命令解析器,类似于windows下的cmd.exe,接收用户命令并调用应用程序。Shell俗称壳,用于区别于核,它作为用户与操作系统内核之间的桥梁,让用户能通过简单命令操作复杂的系统。

ZZH1120KQ的博客 1352

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

shell 编程合订版

shell 既是一种命令语言,又是一种程序设计语言。shell 脚本(shell script),是一种为 shell 编写的脚本程序。shell 不等于 shell script。业界常说的 shell 是指 shell script,本文提到的shell 也是指 shell script。shell 编程跟 JavaScript、PHP 编程一样,只需要文本编辑器和脚本解析器,即可运行已经编辑好的代码。

qq_49120918的博客 1253
上一篇: Java内部类
下一篇: C++虚继承
classify233
博客等级 码龄10年 3粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值