我是靠谱客的博主 风趣世界,这篇文章主要介绍细读shell-4,现在分享给大家,希望可以做个参考。

 17.   /dev/null

$ ls my.file no.such.file 2>/dev/null 

my.file

若要相反:只想看到 stderr 呢?还不简单﹗将 stdout 弄到 null 就行:

$ ls my.file no.such.file >/dev/null 

ls: no.such.file: No such file or directory 

除了用 >/dev/null 2>&1 之外,你还可以如此:  

$ ls my.file no.such.file &>/dev/null 

(提示:将 &> 换成 >& 也行啦~~! ) 

再问:那... 有办法不取消而又"临时"盖写目标档案吗? 

$ set -o noclobber 

$ echo "6" >| file.out 

$ cat file.out 

6 

留意到没有:在 > 后面再加个" | "就好(注意: > 与 | 之间不能有空白哦).... 

再来还有一个难题要你去参透的呢:  

$ echo "some text here" > file 

$ cat < file 

some text here 

$ cat < file > file.bak 

$ cat < file.bak 

some text here 

$ cat < file > file 

$ cat < file

---- 怎么最后那个 cat 命令看到的 file 竟是空的?﹗ 

$ cat < file > file 之后原本有内容的档案结果却被洗掉了﹗ 

这只是 priority 的问题而已

* 在 IO Redirection 中,stdout 与 stderr 的管道会先准备好,才会从 stdin 读进资料。

 file 会先将 file 清空,然后才读进 < file , 

但这时候档案已经被清空了,因此就变成读不进任何资料了... 

在 pipe line 之间,前一个命令的 stderr 是不会接进下一命令的 stdin 的, 

其输出,若不用 2> 导到 file 去的话,它还是送到监视器上面来﹗ 

这点请你在 pipe line 运用上务必要注意的。 

* 在 cm1 | cm2 | cm3 ... 这段 pipe line 中,若要将 cm2 的结果存到某一档案呢?

若你写成 cm1 | cm2 > file | cm3 的话, 

那你肯定会发现 cm3 的 stdin 是空的﹗(当然啦,你都将水管接到别的水池了﹗) 

cm1 | cm2 > file ; cm3 < file 

cm1 | cm2 > file ; cm3 < file 

有的,那就是 tee 命令了。

* 所谓 tee 命令是在不影响原本 I/O 的情况下,将 stdout 复制一份到档案去。 

因此,上面的命令行可以如此打:  

cm1 | cm2 | tee file | cm3 

18.     你要 if 还是 case 呢?  

       comd1 && { 

    comd2 

    comd3 

} || { 

    comd4 

    comd5 

}

若你记得 return value ,我想你也应该记得了 && 与 || 是甚么意思吧? 

用这两个符号再配搭 command group 的话,我们可让 shell script 变得更加聪明哦。 

假如 comd1 的 return value 为 true 的话, 

然则执行 comd3 与 comd4 , 

否则执行 comd4 与 comd5 。

改成if   then        else

if comd1 

then 

    comd2 

    comd3 

else 

    comd4 

    comd5 

fi

可使用 elif 这样的 keyword :

if comd1; then 

    comd2 

elif comd3; then 

    comd4 

else 

    comd5 

fi

若 comd1 为 true ,然则执行 comd2 ﹔ 

否则再测试 comd3 ,然则执行 comd4 ﹔ 

倘若 comd1 与 comd3 均不成立,那就执行 comd5 。

虽然 if 判断式已可应付大部份的条件执行了,然而,在某些场合中,却不够灵活, 

尤其是在 string 式样的判断上,比方如下:  

QQ () { 

    echo -n "Do you want to continue? (Yes/No): " 

    read YN 

    if [ "$YN" = Y -o "$YN" = y -o "$YN" = "Yes" -o "$YN" = "yes" -o "$YN" = "YES" ]

    then 

        QQ 

    else 

        exit 0 

    fi 

} 

QQ

从例中,我们看得出来,最麻烦的部份是在于判断 YN 的值可能有好几种式样。 

.. 

if echo "$YN" | grep -q '^[Yy]([Ee][Ss])*$' 

 

 

QQ () { 

    echo -n "Do you want to continue? (Yes/No): " 

    read YN 

   case "$YN" in 

        [Yy]|[Yy][Ee][Ss]) 

            QQ 

            ;; 

        *) 

 

            exit 0 

            ;; 

    esac 

} 

QQ

我们常 case 的判断式来判断某一变量在同的值(通常是 string)时作出不同的处理, 

比方说,判断 script 参数以执行不同的命令。 

若你有兴趣、且用 Linux 系统的话,不妨挖一挖 /etc/init.d/* 里那堆 script 中的 case 用

法。 

case "$1" in 

  start) 

        start 

        ;; 

  stop) 

        stop 

        ;; 

  status) 

        rhstatus 

        ;; 

  restart|reload) 

        restart 

        ;; 

  condrestart) 

        [ -f /var/lock/subsys/syslog ] && restart || : 

        ;; 

  *) 

        echo $"Usage: $0 {start|stop|status|restart|condrestart}" 

        exit 1 

esac

18.最后要介绍的是 shell script 设计中常见的"循环"(loop)。

bash shell 中常用的 loop 有如下三

* for 

* while 

* until 

for loop 是从一个清单列表中读进变量值,并"依次"的循环执行 do 到 done 之间的命令行。  

for var in one two three four five 

do 

    echo ----------- 

    echo '$var is '$var  

    echo 

done

上例的执行结果将会是:  

1) for 会定义一个叫 var 的变量,其值依次是 one two three four five 。 

2) 因为有 5 个变量值,因此 do 与 done 之间的命令行会被循环执行 5 次。 

3) 每次循环均用 echo 产生三行句子。 

而第二行中不在 hard quote 之内的 $var 会依次被替换为 one two three four

five 。 

4) 当最后一个变量值处理完毕,循环结束。

for ((i=1;i<=10;i++)) 

do 

   echo "num is $i" 

done

除了 for loop ,上面的例子我们也可改用 while loop 来做到:

num=1 

while [ "$num" -le 10 ]; do 

    echo "num is $num" 

    num=$(($num + 1)) 

done

while loop 的原理与 for loop 稍有不同: 

它不是逐次处理清单中的变量值,而是取决于 while 后面的命令行之 return value : 

* 若为 ture ,则执行 do 与 done 之间的命令,然后重新判断 while 后的 return value 。  

* 若为 false ,则不再执行 do 与 done 之间的命令而结束循环。 

 

分析上例:  

1) 在 while 之前,定义变量 num=1 。 

2) 然后测试(test) $num 是否小于或等于 10 。 

3) 结果为 true ,于是执行 echo 并将 num 的值加一。 

4) 再作第二轮测试,其时 num 的值为 1+1=2 ,依然小于或等于 10,因此为

true ,继续循环。 

5) 直到 num 为 10+1=11 时,测试才会失败... 于是结束循环。

 * 若 while 的测试结果永远为 true 的话,那循环将一直永久执行下去:  

* 与 while 相反,until 是在 return value 为 false 时进入循环,否则结束。

因此,前面的例子我们也可以轻松的用 until 来写:

num=1 

until [ ! "$num" -le 10 ]; do 

    echo "num is $num

    num=$(($num + 1)) 

done

或是:  

代码:

num=1 

until [ "$num" -gt 10 ]; do 

    echo "num is $num" 

    num=$(($num + 1)) 

done 

转载于:https://blog.51cto.com/qqtthappygo/955792

最后

以上就是风趣世界最近收集整理的关于细读shell-4的全部内容,更多相关细读shell-4内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(318)

评论列表共有 0 条评论

立即
投稿
返回
顶部