设为首页 收藏本站
查看: 1821|回复: 0

Linux学习笔记(四)——Linux_shell脚本基础

[复制链接]

尚未签到

发表于 2018-8-27 09:44:39 | 显示全部楼层 |阅读模式
  一、  BashShell脚本初步
  之前我们学习了很多Linux命令,但是这些命令都是在命令提示符下执行的,一次只能执行一条命令并产生结果。如创建一个文件或目录等等。但是有些情况下,我们需要执行多个命令来完成一个完整的任务,我们可以在命令行提示符下也可以同时执行多个命令,但需要用分号分割每个单独的命令,如下所示,先定位到当前用户的工作目录下,然后在目录下创建一个logs目录,并且在logs目录中创建一个空的syslog.log日志文件并在日志文件中添加当前的系统日期和时间。
  命令:
  cd  /home/yarn ; mkdir logs ; cd logs ; touch syslog.log ; date > logs.log
  命令执行后,会在/home/yarn目录下首先创建一个目录logs,然后切换到logs目录下,通过touch命令创建一个空的日志文件syslog.log,然后使用date命令将当前系统日期和时间添加到syslog.log日志文件中。
  syslog.log日志内容:
  2016年 02月  18日 星期四  17:49:47 CST
  虽然我们在命令行提示符同时执行了多条命令,也完成了我们想要的任务,但是这样的命令集并没有被保存,不能重复使用,另外,如果任务较复杂,这样的方式就不是更好的方式了。
  9.1           创建一个Bash Shell脚本
  创建一个Bash脚本需要使用文件编辑器,将命令集输入到文本文件中,如下:
  命令:
  vi  bashTest.sh
  bashTest.sh:
  #!/bin/bash
  …
  在脚本的第一行需要输入#!/bin/bash,作用是指定Shell脚本解释器,如果不显示的指定,也可以执行,但是bash提供的函数不能使用。另外的情况是,用户默认的Shell解释器是bash,但是如果其他用户要执行此脚本,这个用户的默认的Shell解释器不是bash,脚本执行过程中可能会出现异常,所以,要求在脚本的第一行要显示的指定Shell脚本解释器。
  在Shell脚本中,#号是用来注释信息的,解释器不会执行#号后面的命令,只把他当中一般的注释信息。注释可以用来说明脚本的使用场景和脚本的使用说明,方便其他用户使用脚本。
  下面创建一个简单的脚本,实现的功能和之前的例子相同,创建目录和日志文件。首先要使用文本编辑器创建一个文本文件用来编写脚本命令。
  命令:
  vi  bash01.sh
  例:bash01.sh:
  #!/bin/bash
  # 创建的第一个bash脚本
  # 此脚本的作用是在用户工作目录下创建一个目录,在目录中创建一个日志文件
  # 并且将当前的系统日期和时间输入到文件中
  # 切换到工作目录
  cd  /home/yarn
  # 创建logs目录
  mkdir  logs
  # 切换到logs目录
  cd logs
  # 创建一个空的日志文件
  touch  syslog.log
  # 将当前系统日期时间添加到syslog.log日志文件中
  date  > syslog.log
  当第一次执行脚本时,系统会警告命令找不到,通常解决的办法有两种,第一种方法是将脚本所在的目录添加到环境变量PATH中,这样系统在执行脚本时会到PATH所指定的目录下去找,找到后执行。另一种方式是使用绝对路径或在脚本所在目录下使用./的方式执行脚本,如下:
  /home/yarn/bash02/bash01.sh
  cd  /home/yarn/bash02
  ./bash01.sh
  如果在环境变量PATH中指定路径或使用绝对路径执行脚本,系统还会发出警告,说用户没有执行的权限,这是因为创建脚本文件时默认情况下是没有执行权限的,如下:
  -rw-rw-r--.  1 yarn yarn  440 2月  19  11:51 bash01.sh
  这和系统默认设置有关,可以重新设置,后面会做介绍。
  看到脚本文件的属主有读写权限而没有执行权限,所以要通过命令chmod为属主设置可执行权限。
  命令:
  chmod  u+x bash01.sh
  bash01.sh:
  -rwxrw-r--.  1 yarn yarn  440 2月  19  11:52 bash01.sh
  好了,现在就可以执行脚本了。
  9.1.1       echo命令
  echo命令是将字符串输出到标准输出,通常使用echo命令输出提示信息或检测结果是否正确。
  命令:
  echo  Test Bash script!
  命令执行后会在控制台输出:Test Bash script!。没问题!因为echo命令默认后面跟着的是字符串,但是有些情况下,输出会出现不正确的结果,如下面的情况:
  命令:
  echo  Test 'Bash script'!
  控制台输出:
  Test  Bash script!
  这不是我们想要的结果,单引号被过滤掉了,所以在使用echo命令时,建议将输出的字符串加上双引号,如下:
  命令:
  echo  "Test 'Bash script'"!
  

  控制台输出:
  Test  'Bash script'!
  这次的输出是我们想要的结果。
  另外,echo命令输出后会自动添加一个换行符,下一次输出将在新行输出,如下:
  命令:
  echo  "Test 'Bash script'"! ; echo "Helle bash"
  

  控制台输出:
  Test  'Bash script'!
  Helle  bash
  有时候我们需要将输出同一行显示,这就需要使用-n参数,如下:
  命令:
  echo -n  "Test 'Bash script'"! ; echo "Helle bash"
  

  控制台输出:
  Test  'Bash script'!Helle bash
  9.2           在Bash脚本中使用变量
  与Java或其他语言相似,在Bash脚本中也可以使用变量,将值保存到变量中在脚本中使用,下面通过例子说明在Bash脚本中变量的使用。在之前我们讲了Linux系统中的环境变量,那么对Bash脚本的变量就更容易理解了。
  9.2.1       Bash脚本中的环境变量
  在Linux系统中维护着一组环境变量,用来记录系统的各类信息,如当前的用户、用户ID和主机名称等等信息,这些环境变量的值可以在Bash脚本中使用。可以通过set命令看到Linux系统维护的环境变量的值。
  命令:
  set
  控制台输出:
  BASH=/bin/bash
  HADOOP_HOME=/usr/local/hadoop
  HISTCONTROL=ignoredups
  HISTFILE=/home/yarn/.bash_history
  HOME=/home/yarn
  HOSTNAME=YARN
  HOSTTYPE=i386
  IFS=$'  \t\n'
  JAVA_HOME=/usr/local/jdk1.8.0_51
  JRE_HOME=/usr/local/jdk1.8.0_51/jre
  LANG=zh_CN.utf8
  LOGNAME=yarn
  OLDPWD=/home/yarn
  PATH=/usr/local/jdk1.8.0_51/bin:/usr/local/jdk1.8.0_51/jre/bin:/usr/lib/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/yarn/bash01:/usr/local/hadoop/sbin:/usr/local/hadoop/bin:/home/yarn/bin:/home/yarn/bash01
  PIPESTATUS=([0]="0")
  PPID=3054
  PWD=/home/yarn/bash02
  UID=500
  USER=yarn
  USERNAME=yarn
  …
  这些环境变量是系统维护的,我们可以在脚本中使用,引用变量需要使用$符号,如下:
  例:在脚本中访问系统环境变量
  #!/bin/bash
  # 使用系统维护的环境变量
  echo "当前的用户:$USER"
  echo "当前用户ID:$UID"
  echo "用户的工作目录:$HOME"
  echo "主机名:$HOSTNAME"
  echo "系统默认脚本解释器:$BASH"
  

  控制台输出:
  当前的用户:yarn
  当前用户ID:500
  用户的工作目录:/home/yarn
  主机名:YARN
  系统默认脚本解释器:/bin/bash
  这里需要注意的是$符,系统会认为后面跟着的是一般变量,在脚本执行过程中,系统会将变量的值替换显示。所以如果想显示$符到控制台,需要进行转义:
  echo "\$USER:$USER"
  $USER:yarn
  对变量的引用可以可以采用${varname}的方式,大括号中是变量名称,修改上面的例子。
  例:采用${varname}的方式访问系统环境变量
  #!/bin/bash
  # 使用系统维护的环境变量
  echo "当前的用户:${USER}"
  echo "当前用户ID:${UID}"
  echo "用户的工作目录:${HOME}"
  echo "主机名:${HOSTNAME}"
  echo "系统默认脚本解释器:${BASH}"
  

  控制台输出:
  当前的用户:yarn
  当前用户ID:500
  用户的工作目录:/home/yarn
  主机名:YARN
  系统默认脚本解释器:/bin/bash
  使用效果是相同的,建议使用第二种方式。
  9.2.2       Bash脚本中的用户变量
  在用户脚本中可以定义和使用变量,定义后的变量可以在脚本中引用。这些变量的生命周期同脚本的执行周期相同,脚本执行结束变量同时在内存中被销毁。为了区别环境变量,用户变量建议使用小写字母,并且变量Var和var是不同的两个变量,要注意变量名区分大小写。
  为变量赋值要使用等号,与其他语言的区别是,变量名、等号和变量值之间是不能存在空格。如下:
  例:
  #!/bin/bash
  name=张三
  age=22
  address=山西太原
  echo "name:$name"
  echo "age:$age"
  echo "address:$address"
  Bash脚本中的变量类型会根据变量的值决定,引用变量需要用到$符。
  例子:编写两个脚本文件,在第一个脚本中调用第二个脚本,父脚本中设置局部变量,在子脚本中进行访问,因为执行子脚本会启动一个新的子进程,所以父脚本中的局部变量不能访问到。
  #!/bin/bash
  #这是一个测试局部变量的脚本
  name=张三
  id=1001
  echo  "name:$name"
  echo  "id:$id"
  echo  "bash02.sh进程号:$$"
  #./bash02_1.sh
  #bash  bash02_1.sh
  #.  ./bash02_1.sh
  source  ./bash02_1.sh
  例子:编写两个脚本文件,在第一个脚本中调用第二个脚本,父脚本中设置环境变量并使用export命令将用户环境变量导出,在子脚本中进行访问父脚本导出的环境变量,因为执行子脚本会启动一个新的子进程,在子进程中可以访问到父脚本中的导出的用户环境变量。
  #!/bin/bash
  #测试用户环境变量
  export  name=zhangsan
  id=1001
  export  id
  echo  "name:$name"
  echo  "id:$id"
  echo  "bash03.sh父进程号:$PPID"
  echo  "bash03.sh进程号:$$"
  bash  /home/yarn/b2/bash03_1.sh
  echo  "name:$name"
  echo  "id:$id"
  例子:编写两个脚本文件,在第一个脚本中使用”.”的方式调用第二个脚本,父脚本中设置局部变量,再设置用户环境变量并使用export命令将用户环境变量导出,在子脚本中进行访问父脚本导出的环境变量和局部变量,因为采用.的方式启动子脚本不会启动一个新的子进程,还是在父进程中运行,所以,在子进程中可以访问到父脚本中的导出的用户环境变量和局部变量。
  #!/bin/bash
  #这是一个测试局部变量的脚本
  name=张三
  id=1001
  echo  "name:$name"
  echo  "id:$id"
  echo  "bash02.sh进程号:$$"
  #./bash02_1.sh
  #bash  bash02_1.sh
  #.  ./bash02_1.sh
  source  ./bash02_1.sh
  9.3           exec命令
  当使用exec命令执行一个命令或启动一个脚本文件时,会启动一个子进程,但进程ID号还会使用父进程的进程ID号,对于父进程的局部变量exec命令启动的脚本进程是不可见的,而父进程导出的环境变量还可以引用到。当exec命令启动的脚本进程执行结束后,不会返回到父进程,而是将父进程终止。也可以理解为exec启动的脚本进程替代了当前的父进程,并继承了父进程的环境变量,当脚本执行结束后启动脚本进程的当前环境都将会被清除。
  语法格式为:
  exec 命令
  通常情况下命令是一个脚本文件。当这个脚本结束时,相应的进程就结束了。
  例子:通常情况下,一个命令或脚本进程结束后,会回到启动命令或脚本进程的父进程,下面例子说明。
  #!/bin/bash
  #测试exec命令启动脚本
  user=zhangsan
  export country="中国"
  echo "bash04.sh进程号:$$"
  exec ./bash04_1.sh
  echo "是否执行到这里"
  例子:通过exec命令启动的命令或脚本进程执行结束后,不会回到启动脚本的父进程,而是会终止启动脚本的父进程,因为使用的进程ID还是父进程的进程ID,感觉上是没有启动新的进程,还在父进程中执行脚本,但是,实际上还是启动了新的子进程(对父进程的环境复制),只是进程ID(PID)还使用父进程的,当脚本执行结束,父进程也不存在了,不存在返回父进程。
  9.3.1    exec命令执行Java程序
  使用exec命令执行Java程序,命令格式如下:

  exec  java>  exec  java -jar jarname
  使用exec命令执行Java程序,当程序执行结束后,执行exec命令的父进程也同样会结束。
  例子:
  9.3.2    exec命令指定文件描述符
  exec命令指定文件描述符在后面的内容中会详细说明。
  例子:重定向输出
  #!/bin/bash
  #测试exec命令重定向输出
  echo  "chongdingxiangqian"
  exec  > log.txt
  echo  "Hello zhangsan"
  cat  bash03.sh
  ls
  9.4           脚本中的反引号
  反引号用于执行命令并且有输出的情况,如:ls,显示目录下的文件信息。并且将输出赋给一个变量。需要注意的是系统会将反引号中的内容作为一个命令并执行。
  反引号可以将命令的标准输出值赋值给一个变量,如下:
  #!/bin/bash
  var=`ls  -a`
  echo "var:$var"
  控制台输出:
  var: .
  ..
  .abrt
  bash01
  .bash_history
  .bash_logout
  .bash_profile
  .bashrc
  .cache
  .config
  .dbus
  .dmrc
  .esd_auth
  …
  下面通过一个例子说明反引号的使用方式。如系统服务每天要创建一个日志文件,每个日志文件名要带有日期。
  例:使用反引号返回日期字符串
  #!/bin/bash
  # 将日期格式化输出结果赋值给变量
  datestr=`date +%y%m%d`
  # 切换到保存日志的目录
  cd /home/yarn/bash01
  # 将日志的名称保存到一个变量中
  logfile=log_${USER}_${datestr}.log
  # 创建一个空的日志文件
  touch $logfile
  # 将当天的日期输入到文件的第一行
  date > $logfile
  生成的文件:
  log_yarn_160226.log
  log160226.log日志内容:
  2016年 02月  26日 星期五  17:29:43 CST
  9.5           获取命令输出结果的另一种方式
  像反引号一样,还可以使用另一种方式获取命令的输出结果。命令格式如下:
  var=$(命令)
  例子:可以用下面的方法读取命令序列的输出,与返引号相似。
  filelist=$(ls  | cat -n)
  echo $filelist
  # 文件列表加行号
  filelist=`ls  | cat -n`
  echo $filelist
  # 计算两个整数的和并返回结果
  result1=`expr 3 + 4`
  result2=$(expr 5 + 5)
  echo $result1
  echo $result2
  # 创建临时文件,并返回文件名称
  tmpfile1=`mktemp`
  tmpfile2=$(mktemp)
  echo $tmpfile1
  echo $tmpfile2
  # 创建临时目录并返回目录名称
  tmpdir1=`mktemp -d`
  tmpdir2=$(mktemp -d)
  echo $tmpdir1
  echo $tmpdir2
  9.6           重定向输入和输出
  重定向是根据不同需求将标准输出到控制台的信息输出到其他的媒介,如将输出到控制台的警告信息重定向输出到日志文件便于查询。或将从标准输入设备键盘读取数据重定向成从文件中读取数据。
  9.6.1       输出重定向
  输出重定向常用的方式是将输出到控制台的信息重定向输出到文件中。输出重定向符是大于号 >,命令格式如下:
  命令 > filename
  只要是有输出信息的命令都可以使用输出重定向符。
  ls -a  > filename
  date  > filename
  echo "login  USER:$USER" > filename
  输出重定向符是大于号,需要注意的是,如果重定向输出的文件不存在,系统会首先创建文件然后将信息输入到文件中,如果文件存在,则直接将信息输入到文件中。通过输出重定向符每次输出的信息都会将文件中已经存在的信息覆盖,所以如果想向文件中追加信息而不覆盖已存在的信息,需要使用重定向符(>>),下面通过例子说明。
  例:将脚本执行过程中的信息重定向输出到日志文件。
  #!/bin/bash
  # 输出重定向
  # 日期格式化到变量
  datestr=`date  +%y%m%d`
  # 日志文件命令
  filename=/home/yarn/bash01/log_${USER}_${datestr}.log
  # 将当天日期重定向输出到日志文件
  date  > $filename
  # 脚本执行信息追加到日志文件
  echo "bash  script begin!" >> $filename
  # 切换到工作目录
  cd  /home/yarn/bash01
  # 将信息追加到日志文件
  echo  "select /home/yarn/bash01" >> $filename
  # 创建工作目录
  mkdir  mapreduce01
  # 将信息追加到日志文件
  echo  "create log dir:/home/yarn/bash01/mapreduce01" >> $filename
  # 切换工作目录
  cd  mapreduce01
  # 将信息追加到日志文件
  echo  "select /home/yarn/bash01/mapreduce01" >> $filename
  # 拷贝文件到当前目录
  cp  /home/yarn/bash01/bash04.sh .
  # 将信息追加到日志文件
  echo  "copy /home/yarn/bash01/bash04.sh to /home/yarn/bash01/mapreduce01"  >> $filename
  # 将脚本执行结束信息追加到日志文件
  echo  "bash script end!" >> $filename
  可以通过:>输出定向符清除文件内容,命令格式如下:
  :> filename
  
  :>会把文件filename截断为0长度,就是清除文件内容。如果文件不存在, 那么就创建一个空的文件。:>是一个占位符和定向符组成。
  例:将输出信息重定向到文件后,将文件信息清除。
  #!/bin/bash
  # :>
  # 定义变量,文件hello.txt不存在
  FILE_DIR=/home/yarn/bash01/dir1/hello.txt
  # 将标准输出到文件中
  # 将"Hello Hadoop!.Hello Bash!"写到/home/yarn/bash01/dir1/hello.txt中
  # 不会在控制台输出,输出重定向到文件中了
  echo  "Hello Hadoop!.Hello Bash!" > "$FILE_DIR"
  # 显示文件/home/yarn/bash01/dir1/hello.txt内容:"Hello Hadoop!.Hello Bash!"
  cat  "$FILE_DIR"
  # 清空/home/yarn/bash01/dir1/hello.txt文件的内容
  :>"$FILE_DIR"
  # 显示文件内容,为空
  cat  "$FILE_DIR"
  exit 0
  例:将输出信息重定向到文件,比较>与>>。
  #!/bin/bash
  # >  >>
  # 定义变量
  FILE_DIR=/home/yarn/bash01/dir1
  # 将"Hello YARN!"写入文件yarn1.txt
  echo  "Hello YARN!" > "$FILE_DIR"/yarn1.txt
  # 显示文件内容:"Hello YARN!"
  cat  "$FILE_DIR"/yarn1.txt
  # 将"Hello MapReduce!"写入文件并覆盖原内容"Hello YARN!"
  echo  "Hello MapReduce!" > "$FILE_DIR"/yarn1.txt
  # 显示文件内容:"Hello MapReduce!"
  cat  "$FILE_DIR"/yarn1.txt
  # 向文件中写入内容:"Hello YARN!"
  echo  "Hello YARN!" > "$FILE_DIR"/yarn2.txt
  cat  "$FILE_DIR"/yarn2.txt
  # 向文件中追加内容:"Hello MapReduce!",在文件尾部添加,不覆盖原内容
  echo  "Hello MapReduce!" >> "$FILE_DIR"/yarn2.txt
  # 显示内容:
  # Hello  YARN!
  # Hello  MapReduce!
  cat  "$FILE_DIR"/yarn2.txt
  exit 0
  9.6.2       输入重定向
  输入标准设备是键盘,输入重定向是将从标准输入设备读取数据重定向到其他媒介,通常情况下,最常见的是重定向输入到文件,从文件中读取数据到命令,和输出重定向正好相反。命令格式如下:
  命令 < filename
  为了测试方便,创建一个文本文件file.txt,文件内容如下:
  abc
  efg
  hello  java
  shell  script
  linux
  hadoop
  100 ok
  50 aaa
  355 399
  25 22  19
  99 1000  345 33
  例子:使用输入重定向符/dev/null
  # 切换到目录
  cd  /home/yarn
  # 拷贝不存在的文件
  cp file1 file2
  执行脚本:
  [yarn@YARN test]$ t.sh || "文件拷贝失败"
  -bash: 文件拷贝失败: command not found
  9.10.3    使用()和{}执行命令序列
  如果想执行一组命令,可以采用两种方式,将命令组放在()或{}中,如果在一行需要使用命令分隔符;将命令分开,如果不在一行,就不需要了。这两种方式的区别是,()可以在命令行上使用,而{}方式只能在脚本中使用。另外,()方式执行脚本不会改变当前命令行状态。
  例子:在命令行执行()语句块
  [yarn@YARN  test]$ (cd /home/yarn;pwd)
  /home/yarn
  [yarn@YARN test]$
  另外,这两种方式的区别是,()方式可以引用父脚本中的变量,但不能改变变量的值,而{}方式可以引用父脚本中的变量,也可以改变变量的值。
  例子:两种方式引用父进程中的局部变量,并修改变量的值,比较两种方式的区别。
  #!/bin/bash
  #测试()和{}
  name=zhangsan
  (
  echo $name
  name=lisi
  echo $name
  echo "()中的进程号: $$"
  )
  echo $name
  echo "bash03.sh进程号:$$"
  #!/bin/bash
  name=zhangsan
  {
  echo $name
  name=lisi
  echo $name
  echo "{}进程号:$$"
  }
  echo $name
  echo "bash04.sh进程号:$$"
  需要注意的是,这两种方式不会启动一个新的子进程,在子进程中执行命令,而是都在父进程中执行。
  例子:在脚本中使用两种方式执行,验证是否创建了新的子进程。
  另外,在()内声明的变量,在脚本中无法访问,相当于局部变量,而在{}内声明的变量在脚本中可以访问
  例子:在()中声明的变量类似局部变量,脚本中不能访问。在{}中声明的变量,脚本中可以访问。
  这两种方式通常使用的场景是重定向输入和重定向输出,从一个文件中读取或重定向输出到文件。
  例子:使用两种方式重定向输入和重定向输出到文件。
  #!/bin/bash
  echo "脚本开始执行"
  (
  cd /home/yarn/b3
  echo "切换到/home/yarn/b3目录下"
  mkdir d6
  echo "创建目录d6"
  cd d6
  echo "切换到d6下"
  touch log.log
  echo "创建日志文件log.log"
  )>f2
  将代码块{…}中的所有标准输出内容都重新定向到文件中,注意,只有标准输出到控制台的内容才会写入到文件中。
  例:代码块的用法。
  #!/bin/bash
  #  {}>file
  FILE_DIR=/home/yarn/bash01/dir1
  # 代码块
  {
  # 判断变量是否是目录
  if [ -d "$FILE_DIR" ]
  then
  # 标准输出到控制台的信息,所以会写到文件中
  echo "Add content to the  '$FILE_DIR/yarn3.txt'"
  # 标准输出已经重定向到文件中了,所以不会显示到控制台,也不会写到文件中
  echo "Bash Sheel!" >>  "$FILE_DIR"/yarn3.txt
  # 同上
  echo "Linux!" >>  "$FILE_DIR"/yarn3.txt
  fi
  # 重新定向到文件中,可以作为日志
  } >  "$FILE_DIR"/bashbak1
  # 显示文件内容:Add content to the  '/home/yarn/bash01/dir1/yarn3.txt'
  cat  "$FILE_DIR"/bashbak1
  从文件中输出内容。
  例:read命令的用法例子。
  #!/bin/bash
  # <
  FILE_DIR=/home/yarn/bash01/dir1/yarn2.txt
  # 从文件中读取第一行到变量line1
  read line1  < "$FILE_DIR"
  # 还是读取第一行
  read  line2 < "$FILE_DIR"
  # 两个变量的内容都是文件的第一行内容:Hello YARN!
  echo  "$line1"
  echo  "$line2"
  # 代码块{…}中读取两次到两个变量,变量line3读取的是第一行
  # 变量line4读取的是文件的第二行
  {
  read line3
  read line4
  } <  "$FILE_DIR"
  echo
  # 输出:Hello YARN!
  echo  "$line3"
  # 输出:Hello MapReduce!
  echo  "$line4"
  9.11       grep命令
  grep命令使用广泛,允许对文本文件中的内容进行模式查找。如果找到匹配模式的信息会输出到控制台,打印符合条件的所有行。创建测试文件flowlist.txt。
  flowlist.txt文件:
  1501010001        71.05 2141618     3       07/11/15  21:46:57        1006 User001     109   4       303
  1501010002        865.86        1686831     2       05/11/15  03:52:44        1009 User009     109   1       302
  1501010003        652.61        2587675     2       07/14/15  19:17:39        1010 User003     110   1       305
  1501010004        905.24        1282788     1       04/17/15  17:14:09        1010 User004     102   3       304
  1501010005        444.25        1624680     1       04/05/15  11:40:51        1005 User009     108   1       308
  1501010006        48.21 2473714     3       01/18/15  23:45:51        1001 User003     110   2       302
  1501010007        396.26        2512994     4       08/07/15  05:55:16        1005 User009     102   2       308
  1501010008        690.74        1259159     2       08/06/15  02:48:20        1004 User001     104   4       304
  1501010009        122.37        2462139     1       04/27/15  08:19:22        1008 User008     105   2       310
  grep命令格式:
  grep [参数] 查找的内容 [文件]
  例子:查找所有以txt结尾的文件中存在字符串的记录并显示到控制台。
  [yarn@YARN test]$ grep "User009" *.txt
  1501010002      865.86   1686831 2       05/11/15  03:52:44       1009    User009  109     1302
  1501010005      444.25   1624680 1       04/05/15  11:40:51       1005    User009  108     1308
  1501010007      396.26   2512994 4       08/07/15  05:55:16       1005    User009  102     2308
  例子:查找存在字符串的行数。
  [yarn@YARN test]$ grep -c "1005" flowlist.txt
  2
  例子:查找存在字符串的记录及行号。
  [yarn@YARN test]$ grep -n "1005" flowlist.txt
  5:1501010005    444.25  1624680 1       04/05/15 11:40:51       1005    User009 108     1308
  7:1501010007    396.26  2512994 4       08/07/15 05:55:16       1005    User009 102     2308
  例子:显示不包含条件的记录。
  [yarn@YARN test]$ grep -v "1005" flowlist.txt
  1501010001      71.05    2141618 3       07/11/15  21:46:57       1006    User001 109     4303
  1501010002      865.86   1686831 2       05/11/15  03:52:44       1009    User009 109     1302
  1501010003      652.61   2587675 2       07/14/15  19:17:39       1010    User003 110     1305
  1501010004      905.24   1282788 1       04/17/15  17:14:09       1010    User004 102     3304
  1501010006      48.21    2473714 3       01/18/15  23:45:51       1001    User003 110     2302
  1501010008      690.74   1259159 2       08/06/15  02:48:20       1004     User001 104     4304
  1501010009      122.37   2462139 1       04/27/15  08:19:22       1008    User008 105     2310
  例子:精确查找符合条件的记录。
  [yarn@YARN test]$grep "303" flowlist.txt
  1501010001      71.05    2141618 3       07/11/15  21:46:57       1006    User001 109     4 303
  例子:忽略大小写查询。
  [yarn@YARN test]$ grep -i "user001" flowlist.txt
  1501010001      71.05    2141618 3       07/11/15  21:46:57       1006    User001  109     4303
  1501010008      690.74   1259159 2       08/06/15  02:48:20       1004    User001  104     4304
  例子:将查询结果通过管道继续查询符合条件的记录。
  [yarn@YARN test]$ grep "User001" flowlist.txt | grep "304"
  1501010008      690.74   1259159 2       08/06/15  02:48:20       1004    User001  104     4304
  例子:将查询结果输出到文件。
  [yarn@YARN test]$ grep "304" flowlist.txt > file_304.txt
  [yarn@YARN test]$ cat file_304.txt
  1501010004      905.24   1282788 1       04/17/15  17:14:09       1010    User004 102     3304
  1501010008      690.74   1259159 2       08/06/15  02:48:20       1004    User001 104     4304
  例子:查询用户信息。
  [yarn@YARN test]$grep "yarn" /etc/passwd
  yarn:x:500:500:yarn:/home/yarn:/bin/bash
  [yarn@YARN test]$ grep yarn /etc/passwd
  yarn:x:500:500:yarn:/home/yarn:/bin/bash
  例子:grep命令不仅可以在文件查找符合条件的行,也可在字符串中查找符合条件的子串。
  [yarn@YARN test]$ echo "Hello Linux" | grep in
  Hello  Linux
  [yarn@YARN test]$echo "I Study Hadoop" | grep "doo"
  I  Study Hadoop
  9.12      变量设置模式
  9.12.1   检查变量是否已经设置值
  测试变量是否已设置值或被初始化。如果变量未被初始化,则返回value。
  命令格式如下:
  var=${var:-value}
  var=${var-value}
  例子:测试变量是否被初始化,如果未被初始化,在返回一个默认的值。
  # 变量name未设初值则返回默认值
  [yarn@YARN test]$echo ${name:-zhangsan}
  zhangsan
  # 可以看出,虽然返回了默认值,但是变量name并未赋值
  [yarn@YARN test]$ echo ${name:-lisi}
  lisi
  # 为变量name赋值
  [yarn@YARN test]$ name=wangwu
  # 因为变量name已经赋值,所以返回变量的值
  [yarn@YARN test]$echo ${name:-zhangsan}
  wangwu
  # 清除变量name
  [yarn@YARN test]$unset name
  # 变量那么未赋初值,返回默认值
  [yarn@YARN test]$ echo ${name:-zhangsan}
  zhangsan
  测试变量是否已设置值或被初始化。如果变量未被初始化,则使用另一个设定的值。与上面命令不同之处在于,将默认值赋值给变量。
  命令格式如下:
  var=${var:=value}
  例子:测试变量是否被初始化,如果未被初始化,在返回一个默认的值并将默认值赋值给变量。
  # 变量id未被赋值,返回默认值并且将值赋给变量id
  [yarn@YARN test]$echo ${id:=1001}
  1001
  # 因为变量id已经赋值1001,所以直接返回
  [yarn@YARN test]$ echo ${id:=1002}
  1001
  # 清除变量id
  [yarn@YARN test]$ unset>
  # 变量id未赋值,返回默认值1002并赋值给变量id
  [yarn@YARN test]$ echo ${id:=1002}
  1002
  # 显示变量id的值,
  [yarn@YARN test]$ echo $id
  1002
  # 因为变量id已经赋值,所以直接返回已有的值
  [yarn@YARN test]$ echo ${id:=1003}
  1002
  测试变量是否已设置值或被初始化。如果变量未被初始化,则返回一个空串。如果已设置初始值,则将新值返回但并不赋值给变量。
  命令格式如下:
  var=${var:+value}
  例子:测试变量是否被初始化,如果未被初始化,在返回一个空串。否则,返回新值但不会将新值赋值给变量。
  # 变量price未被赋初值,返回空串
  [yarn@YARN test]$ echo ${price:+100}
  
  # 如果变量price未赋值,将新值200赋值给变量price
  [yarn@YARN test]$ price=${price:-200}
  # 打印变量的值,为200
  [yarn@YARN test]$ echo $price
  200
  # 如果变量已经赋值,则返回新值,但是并不会将新值赋给变量price
  [yarn@YARN test]$ echo ${price:+100}
  100
  # 打印变量price,变量的值还是旧值200
  [yarn@YARN test]$ echo $price
  200
  9.12.2    设置只读变量
  在声明变量并赋值后,使用readonly命令修饰,变量就成了只读变量,在整个生命周期内不能修改了。
  例子:将变量声明为只读变量。
  # 声明变量并赋值
  [yarn@YARN test]$ name=zhangsan
  # 将变量设置成只读变量
  [yarn@YARN test]$readonly name
  # 打印变量的值
  [yarn@YARN test]$echo $name
  zhangsan
  # 为变量重新赋值,提示为只读不能修改
  [yarn@YARN test]$ name=lisi
  -bash: name:  readonly variable
  # 变量声明时设置为只读
  [yarn@YARN test]$ readonly>
  [yarn@YARN test]$ echo $id
  1001
  # 为变量重新赋值,提示为只读变量
  [yarn@YARN test]$ id=1002
  -bash:>


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-557138-1-1.html 上篇帖子: Shell脚本学习三:生成随机数 下篇帖子: 2.4 shell 脚本基础
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表