随风飞世 发表于 2018-8-19 09:00:15

精讲shell基础以及如何高效的学习shell编程


1、前言
1.1 为什么学习shell编程
  Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具,Linux/UNIX系统的底层及基础应用软件的核心大部分涉及Shell脚本的内容。每一个合格的Linux系统管理员或运维工程师,都需要熟练的编写Shell脚本语言,并能够阅读系统及各类软件附带的Shell脚本内容。只有这样才能提升运维人员的工作效率,适应日益复杂的工作环境,减少不必要的重复工作,从而为个人的职场发展奠定较好的基础
1.2 学好Shell编程所需的基础知识

[*]  能够熟练使用vim编辑器,熟悉SSH终端
[*]  有一定的Linux命令基础,至少需要掌握80个以上Linux常用命令,并能够熟练使用它
[*]  要熟练掌握Linux正则表达式及三剑客命令(grep,sed,awk)
1.3 如何学好Shel编程


[*]  学好Shel编程的核心:多练-->多思考-->再练-->再思考,坚持如此循环即可!
[*]  新手大忌:不可拿来主义,可以模仿,但是要自己嚼烂了吃下去,否则会闹肚子
[*]  格言:你觉得会了并不一定会了,你认为对的并不一定对的
  大家要勤动手,自行完成学习笔记和代码的书写。通过每一个小目标培养自己的兴趣以及成就感
2、Shell脚本入门
2.1 什么是Shell

[*]  Shell是一个命令解释器,它在操作系统的最外层,负责直接与用户对话
  把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出屏幕返回给用户
[*]  这种对话方式可以是:
  1)交互的方式:从键盘输入命令,通过/bin/bash的解释器,可以立即得到shell的回应
  2)非交互的方式:脚本
  下图黄色部分就是命令解释器shell
  Shell的英文意思是贝壳的意思,命令解释器Shell像一个贝壳一样包住系统核心
  Shell执行命令分为两种方式:

[*]  内置命令:
  如讲过的cd,pwd,exit和echo等命令
  当用户登录系统后,shell以及内置命令就被系统载入内存,并且一直运行
[*]  一般命令:如ls,磁盘上的程序文件-->调入-->执行命令
2.2 什么是Shell 脚本
  当linux命令或语句不在命令行下执行(严格说,命令行也是shell)
  而是通过一个程序文件执行时,该程序就被称为Shell脚本或Shell程序
  用户可以在Shell脚本中敲入一系列的命令及语句组合;这些命令
  变量和流程控制语句等有机的结合起来就形成一个功能强大的Shell脚本
  首先先带领大家写一个清空/var/log/messages日志的脚本
  我们需要先想明白几个问题:
  1)日志文件在哪?
  /var/log/messages
  2)用什么命令可以清空文件?
  > 重定向
  3)写一个简单的shell脚本
  #! /bin/bash
  cd /var/log/
  >messages
  4)怎样执行脚本?
  # sh /server/scripts/log.sh
  有没有考虑到:

[*]  有没有脚本放在统一的目录
  /server/scripts目录下


[*]  权限:用哪个用户执行文件
  需要对用户做判断


[*]  清空错文件怎么办,该如何办?
[*]  错误提示:有没有成功知不知道?
[*]  脚本的通用性
  小结:

[*]  Shell就是命令解释器。==>翻译官
[*]  Shell脚本==>命令放在脚本里
3、Shell脚本的建立和执行
3.1 Shell脚本的建立
  推荐使用vim编辑器编辑脚本,可以事先做个别名
# echo "alias vi=vim">>/etc/profile  
# source /etc/profile
3.1.1脚本开头第一行
  规范的Shell脚本第一行会指出由哪个程序(解释器)来执行脚本中的内容
  在linux bash编程中一般为:
#!/bin/bash或#!/bin/sh  其中开头的“#!”又称为幻数,在执行Shell脚本的时候
  内核会根据“#!”后的解释器来确定哪个程序解释脚本中的内容
  注意:这一行必须在每个脚本顶端的第一行,如果不是第一行则为脚本注释行
3.1.2 sh和bash的区别
# ll /bin/shlrwxrwxrwx. 1 root root 4 Dec 23 20:25 /bin/sh -> bash  
# sh是bash的软链接,推荐标准写法#!/bin/bash
  可以看一下系统自带的脚本的写法
  head -1 /etc/init.d/*
3.1.3 脚本注释
  在Shell脚本中,跟在#后面的内容表示注释。注释部分不会被执行,仅给人看
  注释可以自成一行,也可以跟在命令后面,与命令同行。要养成写注释的习惯,方便自己与他人
  最好不用中文注释,因为在不同字符集的系统会出现乱码
3.2 Shell脚本的执行
3.2.1 Shell脚本执行的几种方式
  1)bash scripts-name或sh script-name(推荐使用)
  这种方法是当脚本本身没有可执行权限时常使用的方法
  2)path /script-name 或./scripts-name(全路径或当前路径执行脚本)
  这种方法首先需要给脚本文件可执行权限
  3)source scripts-name或. scripts-name #注意“.”点号,且点号后有空格
  source 或.在执行这个脚本的同时,可以将脚本中的函数和变量加载到当前shell
3.3 Shell脚本开发的规范和习惯
  1)开头指定脚本解释器
  2)开头加版本版权等信息,可配置~/.vimrc文件自动添加
  3)脚本不要用中文注释,尽量用英文注释
  4)脚本以.sh为扩展名
  5)放在统一的目录
  6)代码书写优秀习惯
  a,成对的内容一次性写出来,防止遗漏,如[],'',""等
  b,[]两端要有空格,先输入[]退格,输入2个空格,再退格写
  c,流程控制语句一次书写完,再添加内容
if 条件  
    then
  
      内容
  
fi
  d,通过缩进让代码易读
  e,脚本中的引号都是英文状态下的引号,其他字符也是英文状态
  好的习惯可以让我们避免很多不必要的麻烦,提高工作效率
  
4、Shell环境变量
4.1 什么是变量
  变量就是用一个固定的字符串(也可能是字符数字等的组合),替代更多更复杂的内容
  这个内容里可能还会包含变量和路径,字符串等其他内容。变量的定义是存在内存中
x=1  
y=2
4.2 变量类型
  变量分为两类:
  1)环境变量(也可称为全局变量)
  可以在创建他们的Shell及派生出来的子shell中使用
  环境变量又可以分为自定义环境变量和bash内置的环境变量
  2)局部变量(普通变量):
  只能在创建他们的shell函数或shell脚本中使用,还记得前面的$user?我们创建的一般都是普通变量
4.2.1 环境变量


[*]  环境变量用于定义Shell的运行环境,保证Shell命令的正确执行,Shell通过环境变量来确定登录用户名,命令路径,终端类型,登录目录等,所有的环境变量都是全局变量,可用于所有子进程中
  包括编辑器,shell脚本和各类应用。但crond计划任务除外,还需要重新定义环境变量
[*]  环境变量可以在命令行中设置,但用户退出时这些变量值也会丢失,因此最好在用户家目录下的
  .bash_profile文件中或全局配置/etc/bashrc,/etc/profile文件或者/etc/profile.d/目录中定义
  将环境变量放入profile文件中,每次用户登录时这些变量值都将被初始化
[*]  通常,所有环境变量均为大写。环境变量应用于用户进程前,都应该用export命令导出
  例如:export chensiqi=1
[*]  有一些环境变量,如HOME,PATH,SHELL,UID,USER等,在用户登录前就已被/bin/login
  程序设置好了。通常环境变量定义并保存在用户家目录下的.bash_profile或/etc/profile文件中
4.2.1 局部变量
  定义局部变量
  局部变量在用户当前的shell生存期的脚本中使用。例如,局部变量test取值为test18
  这个值只在用户当前shell生存期中有意义。如果在shell中启动另一个进程或退出,局部变量test值将无效
  普通字符串变量定义
变量名=value  
变量名=‘value’
  
变量名=“value”
  shell中变量名及变量内容的要求

[*]  一般是字母,数字,下划线组成,且以字母开头
  变量的内容,可以使用单引号或双引号印起来,或不加引号
[*]  虽然变量可以以下划线开头,但类似这种变量都是比较特殊的,都是系统自己用的。我们尽量少用
  小结:
  1)CMD=ls的ls两侧的符号是键盘tab键上面的,不是单引号
  2)在变量名前加$,可以取得此变量的值,使用echo或printf命令可以显示变量的值
  $A和$(A)写法不同,效果一样,推荐后面的写法
  3)${WEEK}DAY若变量和其他字符组成新的变量就必须给变量加上大括号{}.
  4)养成将所有字符串变量用双引号括起来使用的习惯,减少编程遇到的怪异错误。“$A”和“${A}”
4.3 变量名及变量内容定义小结

[*]  变量名只能由字母,数字,下划线组成,且以字母开头
[*]  规范的变量名写法定义:见名知意
  a,testAge=1 /dev/null 2>&1
  if [ ! $? -eq 0 ];then
  echo "$user created faile!"
  echo "scripts begin to rollback!"
  for i in ${User}{01..10}
  do
  userdel -r $i >/dev/null 2>&1
  [ $? -eq 0 ] || exit 1
  done
  echo >$Path/user_passwd
  exit 1
  else
  passWD=`echo $RANDOM|md5sum|cut -c1-8`
  [ -d $Path ] || mkdir $Path
  echo $passWD | passwd --stdin $user
  echo "$user:$passWD">>$Path/user_passwd
  fi
  done
11.4.6 获取当前目录下的目录名做为变量列表打印输出
# cat /server/scripts/test.sh  
#!/bin/bash
  

  
Path=`pwd`
  
echo $Path
  
for filename in `ls`
  
do
  
    [ -d ${Path}/${filename} ] && echo $filename
  
done
11.4.7 九九乘法表
# cat /server/scripts/test.sh  
#!/bin/bash
  

  
for ((i=1;i
页: [1]
查看完整版本: 精讲shell基础以及如何高效的学习shell编程