由于我平时的工作环境是linux,所以无可避免的经常使用命令行模式和shell脚本,而且有些命令行每天都要输好多遍,比如ssh登录之类的,所以干脆把平时常用的命令都写成脚本文件,所以特意开了一个shell脚本的分类,用来记录学习shell的过程,以便温习。

  • 首先我们从一个简单的脚本来开启shell学习的大门,假设你想要知道当前系统中有多少人登录,可以使用 who 命令来查询:
1 $ who
2 george        pts/2        Dec 31 16:39
3 betsy         pts/3        Dec 27 11:07
  • 但如果在多用户系统上信息量会很大,在统计时很麻烦,所以我们可以使用通道和wc 程序来统计行数(line)、字数(word)与字符数(character),本例中为统计登录人数所以查询行数即可。
1 $ who | wc -l
2         2
  • 注意:| (管道)符号可以在两个程序之间建立管道:即who 的输出变成了wc 的输入
  • 接下来就可以将其转变为一个小型的脚本文件,将上述命令写入一个一般文本文件中,然后赋予执行权限执行即可,这也展现了脚本文件的开发周期,可以先在命令行进行测试开发,无误后写入文件.
1 $ vi wc.sh
2 #进入文本编辑模式,将命令who | wc -l写入,保存退出
3 $ chmod +x wc.sh #赋予该脚本文件执行权限
4 $ ./wc.sh #执行脚本
5 $     2  #获得输出结果
  • 在很多脚本的第一行都会有#! 这两个字符,这两个字符的含义是告知linux内核应该以哪种shell来执行当前脚本,当前大多数脚本都是使用#!/bin/sh ,也有使用#!/bin/csh (是C shell的解释器)
1 $ cat wc.sh
2 
3 #!/bin/sh
4 who | wc -l
  • 分号; 可用来分割同一行里的多条命令,Shell会依次执行的,如果使用了& 符号,则代表当前命令是后台执行,即不需要等到当前命令执行完毕就可以继续执行下一条命令
  • 变量:Shell变量的名称的开头是一个字母或者下划线符号,后面可以接任意长度的字母、数字和下划线符号,并且变量长度没有限制;变量赋值的方式为:先写变量名称,紧接着= 字符,最后是赋予的值,中间没有空格,当你想取用变量的值则需要在变量的名称前使用$ 字符。
1 $ value=this_is_a_long_value #当赋予的值中存在空格时,需要引号括起来
2 $ echo $value
3 $ this_is_a_long_value
  • 输出命令:大多数人可能习惯使用echo命令来进行简单的输出,但要知道echo是由版本差异的,所以移植是一个可能存在风险的问题,相对来看,还是比较推荐使用printf命令,printf命令几乎完全把c里的printfcopy下来,所以c中的格式化字符也同样适用的。
1 $ printf "hello world.\n" # printf不会像echo那样隐式添加一个换行符,所以需要手动添加换行符\n
2 $ printf “The first program always prints %s %s.\n” Hello World
  • 重定向:以< 改变标准输入,以 > 改变标准输出
1 program < file 可以将program的标准输入修改为file
2 eg. tr -d ‘\r’ < test.file #这条命令会将test.file文件中的回车符删除掉
3 
4 program > file 可以将program的标准输出修改为file
5 eg. tr -d ‘\r’ < test.file > result.file #这条命令会先将test.file中的回车删除,再将处理完的数据输出到result.file中,但test.file中的数据不会发生改变
6 
7 #注意:> 重定向符在目的文件不存在时会自动新建一个,如果文件已存在则会覆盖原有数据,如果希望追加数据,则需要使用 >> 重定向符
  • | 符号建立通道
1 program1 | program2 #program2可以将program1的标准输出作为自己的输入

特殊文件 /dev/null 和/dev/tty

 1 #linux系统提供了两个对Shell编程特别有用的特殊文件
 2 #/dev/null文件
 3 #该文件一般被称为位桶。传送到此文件中的数据都会被系统丢掉,也就是说当程序将数据写入次文件时,从结果上看已经成功写入数据了,但实际上却什么事都没做
 4 #例如测试一个文件是否包含某个模式
 5 if grep pattern myfile > /dev/null
 6 then
 7     printf “find.”
 8 else
 9     printf ”don’t find”
10 fi
11 
12 #/dev/tty
13 #当程序打开此文件时,Linux会自动将它重定向到一个终端再与程序结合
14 eg.printf “Enter new passed:” #提示输入新密码
15    stty -echo #关闭自动打印输入字符的功能
16    read pass < /dev/tty #从当前终端读取密码
17    printf “Enter again:” #再次输入密码
18    read pass2 < /dev/tty
19    stty echo #打开自动打印输入字符的功能
  • stty命令迎来控制终端的各种设置,-echo选项为关闭自动打印每个输入字符的功能,echo选项则是打开该功能
  • 在相对复杂的shell脚本中可以使用set -x 来打开代码追踪功能,使用set +x 来关闭该功能,开启该功能后的代码中,凡是执行过的都会在该行首部添加一个+ 号
1 #!/bin/sh
2 set -x #开启代码追踪功能
3 value=1
4 if [ “$value”x = “0”x ];then #此处在值后面加一个x是规避值为空的情况
5     printf “value is 0.\n”
6 else
7     printf “value isn’t 0.\n”
8 fi
9 set +x #关闭代码追踪功能
  • 输出结果为:
1 + value=1
2 + if [ “$value”x = “0”x ];then
3 printf “value is 0.\n” #由于value的值不为0,所以没有执行这句话,所以首部没有+符号
4 + else
5 + printf “value isn’t 0.\n”
6 + fi
7 + set +x

 

posted on 2017-04-28 17:49  Daniel_z  阅读(515)  评论(0编辑  收藏  举报