继续开始shell十三问中11-13问和后续补充的笔记,加油!


(14)输入重定向与输出重定向

  • “>”是标准输出重定向,可以把输出结果送入文件
  • “<”是标准输入重定向,可以重新指定文件的内容作为输入
  • “2>”是标准错误重定向,可以把命名执行出现的错误提示送入文件

如果你想把标准输出和标准错误输出到一个文件中,可以使用如下的方法

  • $ ls my.file no.such.file 1>file.both 2>&1 (错误到输出)
  • $ ls my.file no.such.file 2>file.both >&2(输出到错误)

使用“<<”追加写入,“<”为最后一次写入的内容
(15)锁定文件避免覆盖写入

$ set -o noclobber
$ echo "4" > file.out
-bash: file: cannot overwrite existing file

如上所示即可避免覆盖写入,当想再次使用后

$ set +o noclobber
$ echo "5" > file.out
$ cat file.out
5

如果想临时的覆盖文档内容,而不取消限制,那么可以使用”>|”

$ set -o noclobber
$ echo "6" >| file.out
$ cat file.out
6

来看一道题,为什么file文件为空

$ 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

[toggle title="点击展开"]
前面提到:$ cat < file > file 之后原本有内容的档案结果却被洗掉了﹗
要理解这一现像其实不难,这只是 priority 的问题而已:
* 在 IO Redirection 中,stdout 与 stderr 的管道会先准备好,才会从 stdin 读进资料。
也就是说,在上例中,> file 会先将 file 清空,然后才读进 < file ,
但这时候档案已经被清空了,因此就变成读不进任何资料了…
[/toggle]
2个问题

$ cat <> file (如果说前面的用优先级解释,但是这个不理解,暂时放一放吧)
$ cat < file >> file

(16)管道内保存数据

在 cm1 | cm2 | cm3 … 这段 pipe line 中,若要将 cm2 的结果存到某一档案呢?
若你写成 cm1 | cm2 > file | cm3 的话,
那你肯定会发现 cm3 的 stdin 是空的﹗(当然啦,你都将水管接到别的水池了﹗)
聪明的你或许会如此解决:

cm1 | cm2 > file ; cm3 < file

虽然这样可行,但是文件I/O会加倍,严重影响效率,所以解决方法是使用tee命令,如下:

cm1 | cm2 | tee file | cm3

(17)几个条件判断
[toggle title="&&与||实现"]

comd1 && {
comd2
comd3
:
} || {
comd4
comd5
}

[/toggle]
[toggle title="if...than...else句式"]

if comd1
then
comd2
comd3
else
comd4
comd5
fi
if comd1; then
comd2
elif comd3; then
comd4
else
comd5
fi

[/toggle]
这个的意思是:意思是说:
若 comd1 为 true ,然则执行 comd2 ﹔否则再测试 comd3 ,然则执行 comd4 ﹔倘若 comd1 与 comd3 均不成立,那就执行 comd5 。

提别一提的是,当than后面不需要接命令的话,可以使用“:”符号占位,这里就不多记录了,和C语言一样,多多的书写实践还能写出得心应手的脚本。

(18)循环

原文写的很简单易懂,我就直接摘过来了~

最后要介绍的是 shell script 设计中常见的”循环”(loop)。
所谓的 loop 就是 script 中的一段在一定条件下反覆执行的代码。
bash shell 中常用的 loop 有如下三种:
* for
* while
* until

for loop 是从一个清单列表中读进变量值,并”依次”的循环执行 do 到 done 之间的命令行。
例:
[toggle title="in句式"]

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 loop 中,变量值的多寡,决定循环的次数。
然而,变量在循环中是否使用则不一定,得视设计需求而定。
倘若 for loop 没有使用 in 这个 keyword 来指定变量值清单的话,其值将从 $@ (或 $* )中继承:

for var; do
....
done

[/toggle]
for loop 用于处理”清单”(list)项目非常方便,
其清单除了可明确指定或从 positional parameter 取得之外,
也可从变量替换或命令替换取得… (再一次提醒:别忘了命令行的”重组”特性﹗)
然而,对于一些”累计变化”的项目(如整数加减),for 亦能处理:

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 :; do
echo looping...
done

一旦你能够理解 while loop 的话,那,就能理解 until loop :
* 与 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

(19)break与continue(与C相同)

这两个命令常用在複合式循环裡,也就是在 do … done 之间又有更进一层的 loop ,
当然,用在单一循环中也未尝不可啦… ^_^

break 是用来打断循环,也就是”强迫结束” 循环。
若 break 后面指定一个数值 n 的话,则”从裡向外”打断第 n 个循环,
预设值为 break 1 ,也就是打断当前的循环。
在使用 break 时需要注意的是, 它与 return 及 exit 是不同的:
* break 是结束 loop
* return 是结束 function
* exit 是结束 script/shell

而 continue 则与 break 相反:强迫进入下一次循环动作。
若你理解不来的话,那你可简单的看成:在 continue 到 done 之间的句子略过而返回循环顶端…
与 break 相同的是:continue 后面也可指定一个数值 n ,以决定继续哪一层(从裡向外计算)的循环,
预设值为 continue 1 ,也就是继续当前的循环。

在 shell script 设计中,若能善用 loop ,将能大幅度提高 script 在複杂条件下的处理能力。
请多加练习吧….

(20)[^ ] 跟 [! ]

通配符(wildcard)知识,暂不记录
“^”是正则表达式中符号,”!”是通配符中的符号,都表示”非”

(21)eval

eval是完成命令重组后再一次重组

a=1
A1=abc
eval echo \$A$a

(22)正则表达式
正则表达式(Regular Expression)知识,暂不记录
(23)grep与egrep与fgrep区别
* grep:
传统的 grep 程式, 在没有参数的情况下, 只输出符合 RE 字串之句子. 常见参数如下:
-v: 逆反模示, 只输出”不含” RE 字串之句子.
-r: 递迴模式, 可同时处理所有层级子目录裡的文件.
-q: 静默模式, 不输出任何结果(stderr 除外. 常用以获取 return value, 符合为 true, 否则为 false .)
-i: 忽略大小写.
-w: 整词比对, 类似 \<word\> .
-n: 同时输出行号.
-c: 只输出符合比对的行数.
-l: 只输出符合比对的文件名称.
-o: 只输出符合 RE 的字串. (gnu 新版独有, 不见得所有版本都支持.)
-E: 切换为 egrep .

* egrep:
为 grep 的扩充版本, 改良了许多传统 grep 不能或不便的操作. 比方说:
- grep 之下不支持 ? 与 + 这两种 modifier, 但 egrep 则可.
- grep 不支持 a|b 或 (abc|xyz) 这类”或一”比对, 但 egrep 则可.
- grep 在处理 {n,m} 时, 需用 \{ 与 \} 处理, 但 egrep 则不需.
诸如此类的… 我个人会建议能用 egrep 就不用 grep 啦… ^_^

* fgrep:
不作 RE 处理, 表达式仅作一般字串处理, 所有 meta 均失去功能.

《Shell十三问》笔记(下)的更多相关文章

  1. 菜鸟教程之学习Shell script笔记(下)

    菜鸟教程Shell script学习笔记(下) 以下内容是学习菜鸟教程之shell教程,所整理的笔记 菜鸟教程之shell教程:http://www.runoob.com/linux/linux-sh ...

  2. 《Shell十三问》笔记(上)

    <shell十三问>是网中人前辈首发在CU论坛上对SHELL的一些整理,非常值得一读 注:笔记的标号非问题标号,而是知识点的标号.本篇笔记记录的是1-10问的知识点 (1)IFS:Shel ...

  3. Shell十三问[转]

    Shell十三问 转载于网络,稍加整理. (一) 为何叫做Shell? 我们知道计算机的运作不能离开硬件,但使用者却无法直接对硬件作驱动,硬件的驱动只能透过一个称为"操作系统(Operati ...

  4. shell十三问

    1) 为何叫做 shell ?在介绍 shell 是甚幺东西之前,不妨让我们重新检视使用者与计算机系统的关系:图(FIXME)我们知道计算机的运作不能离开硬件,但使用者却无法直接对硬件作驱动,硬件的驱 ...

  5. shell十三问:关于${0##*/} 和${0%/*}

    转自shell十三问:  http://bbs.chinaunix.net/thread-218853-1-1.html …… 假設我們定義了一個變量為:file=/dir1/dir2/dir3/my ...

  6. Shell编程笔记

    Shell编程笔记与Windows下熟悉的批处理类似,也可以将一些重复性的命令操作写成一个脚本方便处理.   修改别人的脚本,运行后遇到个问题 setenv: command not found 查证 ...

  7. 转:shell 经典, shell 十三问

      原文链接:http://blog.csdn.net/freexploit/article/details/626660 我在 CU 的日子并不长,有幸在 shell 版上与大家结缘.除了跟众前辈学 ...

  8. shell学习笔记

    shell学习笔记 .查看/etc/shells,看看有几个可用的Shell . 曾经用过的命令存在.bash_history中,但是~/.bash_history记录的是前一次登录前记录的所有指令, ...

  9. 菜鸟教程之学习Shell script笔记(上)

    菜鸟教程之学习Shell script笔记 以下内容是,学习菜鸟shell教程整理的笔记 菜鸟教程之shell教程:http://www.runoob.com/linux/linux-shell.ht ...

随机推荐

  1. WPF学习(10)模板

    在前面一篇我们粗略说了Style和Behaviors,如果要自定义一个个性十足的控件,仅仅用Style和Behaviors是不行的,Style和Behaviors只能通过控件的既有属性来简单改变外观, ...

  2. 将odbc扩展编译至nodejs程序集中

    1. 下载nodejs https://github.com/joyent/node 2. 下载odbc for nodejs 扩展 https://registry.npmjs.org/odbc/- ...

  3. svn import usage and not import .so file

    svn import usage: svn import PATH URL 可以不检查仓库来实现.入文件或目录 for example: svn import /home/scott/xxx svn: ...

  4. Python第一个基本教程6章 抽象的

    Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32 Type "copyri ...

  5. [SignalR]初步认识以及安装

    原文:[SignalR]初步认识以及安装 1.什么是ASP.NET SignalR? ASP .NET SignalR是一个 ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时 ...

  6. POJ 2774 后缀数组:查找最长公共子

    思考:其实很easy.就在两个串在一起.通过一个特殊字符,中间分隔,然后找到后缀数组的最长的公共前缀.然后在两个不同的串,最长是最长的公共子串. 注意的是:用第一个字符串来推断是不是在同一个字符中,刚 ...

  7. Message解析流程(转)

    Message的解析作为一个共同组件.对应不同格式的msg文件有不同的实现类来解析.用SAXParser. 1:Final class MessageResourceManager   在Start方 ...

  8. 【年终分享】彩票数据预测算法(一):离散型马尔可夫链模型实现【附C#代码】

    原文:[年终分享]彩票数据预测算法(一):离散型马尔可夫链模型实现[附C#代码] 前言:彩票是一个坑,千万不要往里面跳.任何预测彩票的方法都不可能100%,都只能说比你盲目去买要多那么一些机会而已. ...

  9. 添加AD验证(域身份验证)到现有网站

    每个网站几乎都会有用户登录的模块,登录就会涉及到身份验证的过程.通常的做法是在页面上有个登录的Form,然后根据用户名和密码到数据库中去进行验证. 而验证后如何在网站的各个页面维持这种认证过的状态,有 ...

  10. FFmpeg 协议初步学习

    typedef struct URLContext { const AVClass *av_class; /**< information for av_log(). Set by url_op ...