现在的位置: 首页 > 综合 > 正文

《shell十三问》下

2018年10月02日 ⁄ 综合 ⁄ 共 4516字 ⁄ 字号 评论关闭

八、$(()) 与 $() 还有${} 差在哪?

8.1  $()  同 ·· 做命令替换

        ·· 与 ‘’ 容易混淆。

        ·· 在符合替换时,需要 \` 。

        $() 不是在每种shell上都可以使用, ·· 在所有unix shell上都可以使用。

8.2 ${var} 与 $var 去变量值

        ${var} 范围更准确。

        ${} 更强大的功能待看。

8.3 $(()) 做整数运算

        支持的整数运算符号:+、 -、 *、 /、  %、  &、 |、 ^、 !。

        其中的变量可以用$取,也可以不用。

        支持不同进位(二、八、十六进制)做运算、输出十进制。

8.4 (())重定义变量值或作testing

        ((a++))

        ((a<b)) //当前用的shell上不支持

九、$@ 与 $* 差在哪?

9.1 $0 是shell script名称(路径)

        function是script中的script,也有positional parameter。

        function中的$0是外部script名称(路径)。

9.2 $10

        $10不是ten,而是one0。

        取第10个参数的值:

                ${10}

                用shift 1

9.3 $@ 与 $#

       $@ 与 $# 只有在soft quote中才有差异,否则表示“全部参数”($0除外)。

#!/bin/bash

my_fun() {
        echo "$#"
}


echo 'the number of parameter is "$@" is '$(my_fun "$@")
echo 'the number of parameter is "$*" is '$(my_fun "$*")

        执行结果:

十、&& 与 || 差在哪?

10.1 Return Value(RV)

        Return Value(RV):

                shell下的每一个command或function,在结束的时候都会传回给父进程一个值,称为Return Value(RV)。

                在script里,用exit RV来指定其值,若没有指定,结束时最后一条命令的RV作为其值。

                在function里,用return RV指定其值。

        Return Value(RV)值:

                Return Value(RV)取值范围0-255。

                $? 取Return Value(RV)值。

        Return Value(RV)用来判断进程的退出状态(exit status):

                0 为“真”(true)。

                非0 为假(false)。

10.2 test测试return value

        test expression 

        [ expression ]

        测试对象只支持三种:string、integer、file

        expression1 -a expression2

        expression1 -o expression2

10.3 && 与 ||

        expression1 && expression2 :expression2 在expression1为“真”的情况下,才执行。

        expression1 || expression2 :expression2 在expression1为“假”的情况下,才执行。

十一、> 与 < 差在哪?

11.1 File Descriptor (FD)

        0 :Standard Input (STDIN)                    默认设备:keyboard

        1 :Standard Output (STDOUT)             默认设备:monitor

        2 :Standard Error Output (STDERR)   默认设备:monitor

11.2 重定向输入/输出

        < : 改变读进的数据信道(stdin)。

       0< :0< 同 < , < 符号之前需要制定一个FD,默认为0。

       << :输入一段文本,直到读到<<后指定的内容。

        > :改变输出的数据信道(stdout)。

       1> :1> 同 > ,1是 > 默认的FD。

       2> :改变错误的数据信道(stderr)。

        >> :> 重定向输出到文件,会覆盖原来的内容。 >> 会追加输出到文件末尾。

        set -o noclobber :使得 > 不能覆盖已经存在的文件。

        set +o noclobber :使得 > 可以覆盖已经存在的文件。

        >| :设置set -o noclobber后,使用 >| 可以临时覆盖已经存在的文件。

11.3 /dev/null

         command  >  /dev/null

        将stdout、stderr输出到/dev/null:

                command  >  /dev/null  2>&1

                command  &>  /dev/null

                command  >&  /dev/null

11.4 优先级

        cat < file >file    从file读入、输出到file。 结果文件的内容为空。

        先准备好stdout和stderr管道,再从stdin读取。

11.5 管道pipe line

        上一条命令的stdout接到下一条命令的stdin。

        上一条命令的stderr不会接到下一条命令的stdin。

        cmd1 | cmd2 | cmd3:

                想让cmd2的内容输出到file中,并传递给cmd3

                cmd1 | cmd2 > file | cmd3 < file                 file I/O变双倍。

                cmd1 | cmd2 | tee file | cmd3                     tee在不影响原本IO的情况下,将stdout复制到file中去。

十二、你要 if 还是 case 呢?

12.1 if

#!/bin/bash

if [ $1 -lt $2 ]
then
        echo "$1 is less than $2"
elif [ $1 -eq $2 ]
then
        echo "$1 is equal $2"
else
        echo "$1 is great than $2"
fi

输出结果:

12. case

#!/bin/bash

case $1 in
        [Yy]|[Yy][Ee][Ss])
        echo "yes"
        ;;
        [Nn]|[Nn][Oo])
        echo "no"
        ;;
        *)
        echo "other"    
        ;;
esac

十三、for what? while 与 until 差在哪?

13.1 for

#!/bin/bash

for m in a b c
do

        for((n=1;n<5;n++))
        do
                echo "m,n is: $m $n"

                if [ $n -gt 2 ]
                then
                        continue 2
                fi

                if [ $m = c ]
                then
                        break 2
                fi
        done
done

输出结果:

13.2 while

while循环:

#!/bin/bash

num=1
while [ $num -lt 10 ]
do
        echo "\$num is $num"
        num=$(($num + 1))
done

死循环:

#!/bin/bash

while :;
do
        echo "hello"
done

13.3 until

until循环:

#!/bin/bash

num=1
until [ $num -ge 10 ]
do
        echo "\$num is $num"
        ((num++))
done

13.4 break、continue

        break n 

                “从里往外”打断第n个循环。(n 默认值为1 )

        continue n 

                “从里往外”继续第n个循环。(n 默认值为1 )

        break 结束 loop

        return 结束 function

        exit 结束 script/shell

十四、[^ ] 与 [! ] 差在哪

 [^ ] 与 [! ] 的区别,就是Wildcard 与 Regular Expression 的区别。

        command line format : command_name options arguments

        变量替换: 先替换,再重组 command line

14.1 wildcard

        wildcard是一种命令行的路径扩展(path expansion)功能。

        只作用在command line的argument中的path之上。

        常见的wildcard:

                * :匹配0或多个字符。

                ?:匹配任意一个字符。

                [list] :匹配list中的任意一个字符。

                [!list] :匹配不在list中的任意一个字符。

                {string1, string2, ...} :匹配string1、sting2、...中的一个字符串。

                string也可以ASCII的起止范围,如a-d。

        注意:

                [! ] 中的 !只有放在第一位时,才有排除功能。

                [ - ] - 左右两边均有字符时,才表示一段范围,否则做“-”(减号)处理。

                以 * 或 ? 开始的wildcard不能匹配隐藏文件。

14.2 Regular express(RE)

        Regular express(RE)只用于“字符串处理”的程序之中,与路径名称一点关系都没有。

        Regular express(RE)所处理的字符串是指纯文档或透过stdin读进的内容。

        不少shell meta与RE的meta是冲突的:

                shell command line中有meta和literal, RE中也有meta和literal (RE中用escape(\)关闭meta)。

                不少shell meta与RE的meta是冲突的。 

                例如:* 在RE里是一个modifier(后述),在command line上是一个wildcard。

                解决办法:用shell quoting,关掉 shell meta。

        锚点(anchor):

                ^ :表示句首

                $ :表示句尾

                \< :表示词首

                \> :表示词尾

        修饰字符(modifier):

                * :出现0次或多次。

                ? :出现0次或1次。

                + :出现1次或多次。

                {n} :出现n次。

                {n, m} :出现n到m次。

14.3 grep、egrep、fgrep区别

        grep:

        egrep:

                grep下不支持 ? 与 + 这两种modifier,但egrep可以。

                grep不支持a|b或(abc|xyz)这类“或一”比对,但egrep可以。

                grep在处理{n, m}时,需用\{ 与 \} 处理,但egrep不需。

        fgrep:

               不做RE处理,表达式仅做一般字符串处理,所有meta均失去功能。

抱歉!评论已关闭.