Shell脚本编程初体验

发表于:2015-6-10 10:00

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Petras Liumparas    来源:51Testing软件测试网采编

分享:
  这些就是你需要知道的,关于重定向的几乎所有内容了。我是说几乎,因为还有一个更为重要的重定向工具,它称之为“管道”。通过使用|(管道)符号,我们通常重定向stdout流。
  比如说,我们有这样一个文本文件:
  [root@localhost ~]
  # cat text_file.txt
  This line does not contain H e l l o word
  This lilne contains Hello
  This also containd Hello
  This one no due to HELLO all capital
  Hello bash world!
  而我们需要找到其中某些带有“Hello”的行,Linux中有个grep命令可以完成该工作:
  [root@localhost ~]
  # grep Hello text_file.txt
  This lilne contains Hello
  This also containd Hello
  Hello bash world!
  [root@localhost ~]
  #
  当我们有个文件,想要在里头搜索的时候,这用起来很不错。当如果我们需要在另一个命令的输出中查找某些东西,这又该怎么办呢?是的,当然,我们可以重定向输出到文件,然后再在文件里头查找:
  [root@localhost ~]
  # fdisk -l>fdisk.out
  [root@localhost ~]
  # grep "Disk /dev" fdisk.out
  Disk /dev/sda: 8589 MB, 8589934592 bytes
  Disk /dev/mapper/VolGroup-lv_root: 7205 MB, 7205814272 bytes
  Disk /dev/mapper/VolGroup-lv_swap: 855 MB, 855638016 bytes
  [root@localhost ~]
  #
  如果你打算grep一些双引号引起来带有空格的内容呢!
  注意:fdisk命令显示关于Linux操作系统磁盘驱动器的信息。
  就像我们看到的,这种方式很不方便,因为我们不一会儿就把临时文件空间给搞乱了。要完成该任务,我们可以使用管道。它们允许我们重定向一个命令的stdout到另一个命令的stdin流:
  [root@localhost ~]
  # fdisk -l | grep "Disk /dev"
  Disk /dev/sda: 8589 MB, 8589934592 bytes
  Disk /dev/mapper/VolGroup-lv_root: 7205 MB, 7205814272 bytes
  Disk /dev/mapper/VolGroup-lv_swap: 855 MB, 855638016 bytes
  [root@localhost ~]
  #
  如你所见,我们不需要任何临时文件就获得了相同的结果。我们把fdisk stdout重定向到了grep stdin。
  注意 : 管道重定向总是从左至右的。
  还有几个其它重定向,但是我们将把它们放在后面讲。
  在shell中显示自定义信息
  正如我们所知道的,通常,与shell的交流以及shell内的交流是以对话的方式进行的。因此,让我们创建一些真正的脚本吧,这些脚本也会和我们讲话。这会让你学到一些简单的命令,并对脚本的概念有一个更好的理解。
  假设我们是某个公司的总服务台经理,我们想要创建某个shell脚本来注册呼叫信息:电话号码、用户名以及问题的简要描述。我们打算把这些信息存储到普通文本文件data.txt中,以便今后统计。脚本它自己就是以对话的方式工作,这会让总服务台的工作人员的小日子过得轻松点。那么,首先我们需要显示提问。对于显示信息,我们可以用echo和printf命令。这两个都是用来显示信息的,但是printf更为强大,因为我们可以通过它很好地格式化输出,我们可以让它右对齐、左对齐或者为信息留出专门的空间。让我们从一个简单的例子开始吧。要创建文件,请使用你惯用的文本编辑器(kate,nano,vi,……),然后创建名为note.sh的文件,里面写入这些命令:
  echo "Phone number ?"
  如何运行/执行脚本?
  在保存文件后,我们可以使用bash命令来运行,把我们的文件作为它的参数:
  [root@localhost ~]
  # bash note.sh
  Phone number ?
  实际上,这样来执行脚本是很不方便的。如果不使用bash命令作为前缀来执行,会更舒服一些。要让脚本可执行,我们可以使用chmod命令:
  [root@localhost ~]
  # ls -la note.sh
  -rw-r--r--. 1 root root 22 Apr 23 20:52 note.sh
  [root@localhost ~]
  # chmod +x note.sh
  [root@localhost ~]
  # ls -la note.sh
  -rwxr-xr-x. 1 root root 22 Apr 23 20:52 note.sh
  [root@localhost ~]
  #
  注意 : ls命令显示了当前文件夹内的文件。通过添加-la键,它会显示更多文件信息。
  如我们所见,在chmod命令执行前,脚本只有读(r)和写(w)权限。在执行chmod +x后,它就获得了执行(x)权限。(关于权限的更多细节,我会在下一篇文章中讲述。)现在,我们只需这么来运行:
  [root@localhost ~]
  # ./note.sh
  Phone number ?
  在脚本名前,我添加了 ./ 组合。.(点)在unix世界中意味着当前位置(当前文件夹),/(斜线)是文件夹分隔符。(在Windows系统中,我们使用反斜线 \ 表示同样功能)所以,这整个组合的意思是说:“从当前文件夹执行note.sh脚本”。我想,如果我用完整路径来运行这个脚本的话,你会更加清楚一些:
  [root@localhost ~]
  # /root/note.sh
  Phone number ?
  [root@localhost ~]
  #
  它也能工作。
  如果所有linux用户都有相同的默认shell,那就万事OK。如果我们只是执行该脚本,默认的用户shell就会用于解析脚本内容并运行命令。不同的shell的语法、内部命令等等有着一丁点不同,所以,为了保证我们的脚本会使用bash,我们应该添加#!/bin/bash到文件首行。这样,默认的用户shell将调用/bin/bash,而只有在那时候,脚本中的命令才会被执行:
  [root@localhost ~]
  # cat note.sh
  #!/bin/bash
  echo "Phone number ?"
  直到现在,我们才100%确信bash会用来解析我们的脚本内容。让我们继续。
  读取输入
  在显示信息后,脚本会等待用户回答。有个read命令用来接收用户的回答:
  #!/bin/bash
  echo "Phone number ?"
  read phone
  在执行后,脚本会等待用户输入,直到用户按[ENTER]键结束输入:
  [root@localhost ~]
  # ./note.sh
  Phone number ?
  12345 <--- 这儿是我输入的内容
  [root@localhost ~]
  #
  你输入的所有东西都会被存储到变量phone中,要显示变量的值,我们同样可以使用echo命令:
  [root@localhost ~]
  # cat note.sh
  #!/bin/bash
  echo "Phone number ?"
  read phone
  echo "You have entered $phone as a phone number"
  [root@localhost ~]
  # ./note.sh
  Phone number ?
  123456
  You have entered 123456 as a phone number
  [root@localhost ~]
  #
  在bash shell中,一般我们使用$(美元)符号来表明这是一个变量,除了读入到变量和其它为数不多的时候才不用这个$(将在今后说明)。
  好了,现在我们准备添加剩下的问题了:
  #!/bin/bash
  echo "Phone number?"
  read phone
  echo "Name?"
  read name
  echo "Issue?"
  read issue
  [root@localhost ~]
  # ./note.sh
  Phone number?
  123
  Name?
  Jim
  Issue?
  script is not working.
  [root@localhost ~]
  #
  使用流重定向
  太完美了!剩下来就是重定向所有东西到文件data.txt了。作为字段分隔符,我们将使用/(斜线)符号。
  注意 : 你可以选择任何你认为是最好的分隔符,但是确保文件内容不会包含这些符号在内,否则它会导致在文本行中产生额外字段。
  别忘了使用“>>”来代替“>”,因为我们想要将输出内容附加到文件末!
  [root@localhost ~]
  # tail -2 note.sh
  read issue
  echo "$phone/$name/$issue">>data.txt
  [root@localhost ~]
  # ./note.sh
  Phone number?
  987
  Name?
  Jimmy
  Issue?
  Keybord issue.
  [root@localhost ~]
  # cat data.txt
  987/Jimmy/Keybord issue.
  [root@localhost ~]
  #
  注意 : tail命令显示了文件的最后的n行。
32/3<123>
2023测试行业从业人员调查问卷已开启,千元大奖正在等你~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2023
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号