[关闭]
@perkyoung 2015-07-12T14:35:34.000000Z 字数 3597 阅读 1681

shell编程学习总结-3

运维


编写和调试脚本

建立并且运行一个脚本

script.sh

  1. #!/bin/bash
  2. echo "the script starts now."
  3. echo "Hi, $USER!"
  4. echo
  5. echo "I will now fetch you a list of connected users:"
  6. echo
  7. w
  8. echo
  9. echo "I'm setting two variables now."
  10. export COLOUR="red"
  11. COLOUR="black"
  12. VALUE="9"
  13. echo "this is stinrg : $COLOUR"
  14. echo "and this is a number: $VALUE"

在终端中执行这个脚本的,父进程会创建一个子进程,在子进程中执行这个脚本的内容。当子进程退出时候,控制权再次交给父进程,所以在子进程中创建的变量都会失效。包括export是变量,或者export改变的原有的变量的值,都会失效。

如果想用一个脚本调用另外一个脚本,并且需要另外一个脚本中的变量值,就需要source ./script.sh,这个意思是不创建进程,而是在当前脚本中执行,和sh中的'.'的意思是一样的,而且被调用的脚本也不需要有可执行权限。

脚本基础

#!/bin/bash决定要启用的shell
脚本最好要在首部写上此脚本的作用,如果在其他行的关键部位也有注释,就更好了

调试脚本

  1. 调试整个脚本
  2. sh -x ./script.sh
  3. 调试部分脚本
  4. set -x
  5. code..........
  6. set +x

Bash环境

shell初始化文件

/etc/profile,/etc/inputrc,/etc/profile.d
这些配置文件应用到了所有用户。
/etc/profile,为每个用户设置环境信息,当用户第一次登陆时候运行

~/.bash_profile
用户其实需要增加针对自己的配置,或者更改默认设置。这时候就是这个文件了。这个文件一般也会执行 ~/.bashrc,~/.bash_login

~/.bash_login
这个文件包含了只有你在登陆系统的时候才执行的特殊设置,本机的ubuntu系统没有这个文件,一般情况下,在没有~/.bash_profile的时候才会找这个文件,如果同时存在这两个文件,那一般情况下,在~/.bash_profile中,也会执行了~/.bash_login

~/.profile
在没有~/.bash_profile, ~/.bash_login~的情况下,才会读取这个文件

~/.bashrc
在大多数情况下,是使用非登陆shell的,比如你的桌面linux,打开终端,从来没有让亲输入过用户名密码吧;无需认证;同时他也会读取登陆时的配置文件,所以无需重复添加。一般系统中不存在/etc/bashrc。这个文件中用户就可以自定义一些想立即生效的变量或者别名。利用xshell远程的ssh登陆时,会执行~/.bash_profile,也会执行~/.bashrc,如果复制一个xshell,仅会执行~/.bashrc

如何生效
重新连接系统或者source file这个配置文件。多数 shell 脚本在一个私有环境中执行:除非变量是父脚本 export 出来的,不然他们不会被子进程继承下来。

变量

变量的类型

全局变量
全局变量或者环境变量存在于所有的shell当中,printenv或env可以输出他们
本地变量
set可以显示所有变量的列表,包括环境变量和函数

建立变量

一般的变量只存在于当前shell,子shell不会知晓,

  1. $full_name="perkyoung"
  2. $bash
  3. $echo $full_name
  4. //该值为空,因为那个变量是本地变量

想让子shell知道,就需要导出该变量,export full_name,导出的变量就像环境变量一样,对子shell可见,但是子shell对该导出变量做的更改,不会影响父shell本身

  1. $full_name="perkyoung"
  2. $export full_name
  3. $bash
  4. $echo $full_name
  5. perkyoung
  6. $export full_name="liguoli"
  7. $exit
  8. $echo $full_name
  9. perkyoung

正则表达式

流编辑器SED

字符匹配

  1. sed '/errors/p' example #匹配包含errors的行并输出,但是会输出两次
  2. sed -n '/errors/p' example #这个只输出了一次
  3. sed '/errors/d' example #删除包含errors的行

行匹配

  1. sed '2,4d' example #删除2-4行
  2. sed '3,$d' example #3-最后一行
  3. sed '/a text/,/This/p' example #从``a text``到``This``的行

查找替换

  1. sed 's/erors/errors/g' example
  2. sed 's/^/>/g' example #行首插入>
  3. sed 's/$/EOL/g' example #行尾插入EOL
  4. sed 's/erors/errors/g' -e 's/last/final/g' example

流编辑器AWK

条件语句

数字比较

  1. #!/bin/bash
  2. if [ ! -f ./aaa ] ; then
  3. echo "./aaa is not exist."
  4. fi
  5. LINENUM=`wc -l ./aaa`
  6. echo $LINENUM # result is : 3 ./aaa
  7. if test "$LINENUM" == "3" #字符串的比较,喜欢用test替代[]
  8. then
  9. echo "line num is 3"
  10. fi
  11. if test "$LINENUM" -eq "3" #因为LINENUM包括字母,所以-eq就会有语法错误,只能用==进行字符串的比较
  12. then
  13. echo "....."
  14. fi
  15. LINENUM=$(wc -l ./aaa | cut -f1 -d" ") #取一个命令行行的结果的另一种方法
  16. echo $LINENUM #3
  17. if test "$LINENUM" -eq "3" ; then #只要LINENUM是数字,那无论是否是引号,或者换成==,都正确
  18. echo "...."
  19. fi

字符串比较

  1. if test $(whoami) == 'perkyoung'
  2. then
  3. echo "is perkyoung"
  4. fi

正则表达式匹配

  1. #!/bin/bash
  2. gender="192.168"
  3. if [[ "$gender" =~ [0-9]{3}\.[0-9]+ ]] #两个双括号匹配
  4. then
  5. echo "yes"
  6. fi
  7. NAME="perkyong"
  8. REG='.+y.+'
  9. if [[ $NAME =~ $REG ]]
  10. then
  11. echo "yes"
  12. fi

获取命令的返回状态

  1. if ! grep $USER /etc/passwd 1>/dev/null #获取grep的返回状态,目测应该不是返回值,因为如果匹配到,返回值是0,取非之后是1,但是却没有走到下面的分支
  2. then
  3. echo "have NO the account"
  4. fi
  5. YEAR=`date +%Y`
  6. if test $[$YEAR % 4] -eq "0" #在中括号种进行运算,如果是命令的话,可以用`或者小括号
  7. then
  8. echo "run nian"
  9. else
  10. echo "no run nian"
  11. fi
  12. if test $[$YEAR % 4] == "0" && (test $[$YEAR % 4] != "1" || ..... ) #将test换成[]也行,
  13. then
  14. echo "....."
  15. fi
  16. SPACE="anquan"
  17. case $SPACE in
  18. start)
  19. echo "anquan"
  20. ;;
  21. end)
  22. echo "bu anquan"
  23. ;;
  24. *)
  25. echo "default"
  26. ;;
  27. esac

编写交互脚本

显示用户消息

  1. echo -e "name\tage" #-e选项可以用来专业反斜杠
  2. echo -n "input:" #-n选项不输出换行符

捕获用户输入

  1. read name

重定向和文件描述符

  1. $exec 100>./result #指定文件描述符给文件
  2. $ls -l * >& 100 #文件内容输出到该文件
  3. $cat ./test
  4. hello world perkyoung
  5. exec 7<&0
  6. exec < ./test #test内容是
  7. read name1 name2 name2
  8. echo $name2 # hello
  9. echo $name2 # world
  10. echo $name3 # perkyoung
  11. exec 7<&- $关闭文件描述符

函数

  1. #!/bin/bash
  2. echo $(uname) #shell解释性语言,不会是别处后面的uname,输出系统自带的uname命令结果
  3. num=1000
  4. uname(){
  5. echo "test!"
  6. num=$[$num+1]
  7. return 100
  8. }
  9. testvar()
  10. {
  11. local num=10
  12. num=$[$num+1]
  13. echo $num
  14. }
  15. uname #调用自身定义的uname函数
  16. echo $? #获取返回值100
  17. echo $num #uanme函数改变的是全局的num值
  18. testvar
  19. echo $num #testvar改变的是局部变量的num,对外界没有影响
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注