Shell脚本编程基础

1. Shell简介

1.1 什么是Shell

  • 概念: Shell即使一种命令语言,也是一个用C语言编写的程序(命令解析器)。
  • 作用: 主要提供一个借口使用户与内核交操作。
  • 流程: 接受用户输入的命令并且进行解释(转换为计算机可以理解的机器码),然后将命令送入内核去执行,最后将结果返回给用户。
    Linux系统结构.png

1.2 Shell的种类

  • 含义:不同的命令解析器(程序不断升级)
  • 区别:提示符不同、语法不同、展示效果不同等
  • 常用:sh、csh、ksh、bash等

sh (Bourne Shell) AT&T Bell实验室的Steve Bourne开发 (最早的)
csh (C Shell) 加州伯克利大学的Bill Joy (更强)
ksh (Korn Shell) AT&T Bell实验室的David Korn开发 (升级)
bash(Bourne Again Shell) 自由软件基金会(GNU)开发的一个Shell (统一)

  • 常见命令:
命令 含义
cat /etc/shells 查看系统支持的shell类型
echo $SHELL 查看当前使用的shell类型
useradd [参数] 用户名(-g 指定用户组,-c 备注,-s 登录执行的命令,-d 家目录) 用户添加
usermod 参数 用户名(以上四个 + -l 改名) 用户编辑
userdel 用户名 用户删除
passwd 用户名 修改密码

例如:修改test用户的登录执行命令种类为bash
sudo usermod -s /bin/bash test1

2. Shell脚本

除了挨个执行命令外,还一个创建一个脚本文件批量处理。
创建脚本并执行的步骤:

  • 创建一个脚本文件并用vi模式打开:
vi test.sh 
# 可以不加后缀
  • 指定运行脚本文件的命令解析器类型,在脚本文件中写入代码:
#!/bin/bash 
# 指定为bash类型
  • 写入要执行的代码:
echo hello  
# 输出字符串hello
  • 执行脚本语法:
编号 方法
方法1 sh 路径及文件名(推荐)
方法2 /bin/bash 路径及文件名
方法3 source 路径及文件名
方法4 . 路径及文件名.sh

3. Shell变量

3.1 本地变量

  • 概念:只对当前shell进程有效(ps. 对当前进程的子进程和其它shell进程无效)
  • 语法:

设置:变量名=变量值(等号不能有空格)
删除:unset 变量名
输出:echo $变量名

MacBook-Pro:~ test$ VAR_T1=123        #定义变量
MacBook-Pro:~ test$ echo $VAR_T1      #输出变量
123
MacBook-Pro:~ test$ echo ${VAR_T1}456      #输出变量,添加{}避免混淆
123456
MacBook-Pro:~ test$ unset VAR_T1      #删除变量
MacBook-Pro:~ test$ echo $VAR_T1

3.2 环境变量

  • 概念:对当前shell进程和子进程有效,其他shell进程无效。通过修改配置文件,可以定义全局都生效的环境变量。
  • 语法:

export 变量名=变量值
对所有shell进程都生效:
vi /etc/profile #在该配置文件中定义环境变量
source /etc/profile #让新建立的环境变量立刻生效无需重新启动系统

3.3 局部变量

  • 概念:函数调用时创建、调用完毕时销毁。
  • 语法:

local 变量名=变量值

MacBook-Pro:~ test$ function a(){
> local VAR_T2=123
> echo $VAR_T2
> }
MacBook-Pro:~ test$ a
123
MacBook-Pro:~ test$ echo $VAR_T2

3.4 位置变量

  • 概念:指程序运行时动态传入的参数。
  • 语法:

传参:sh 路径及文件名.sh 参数1 ... 参数n
输出:echo $1 / .. / echo $n

MacBook-Pro:shell test$ cat test3.sh 
#!/bin/bash
echo $[${1}+${2}]  #算数代换
MacBook-Pro:shell test$ sh test3.sh 5 5
10

3.5 特殊变量

  • 特殊变量的介绍
变量 含义
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$# 传递给脚本或函数的参数个数。
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。
$? 上个命令的退出状态,或函数的返回值。
$$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
  • 特殊变量的应用场景
变量 应用场景
$n 根据传递的参数安装指定软件
$$ 脚本执行时输出进程编号便于卡死时结束进程(注:sleep 秒数)

3.6 其他

3.6.1 命令代换
  • 概念:通过语法反引号或$(名称)实现先解析shell指令,再赋值给变量。
  • 示例:
MacBook-Pro:shell test$ VARDATE=date
MacBook-Pro:shell test$ echo $VARDATE
date
MacBook-Pro:shell test$ VARDATE=`date`
MacBook-Pro:shell test$ echo $VARDATE
2018年10月29日 星期一 20时12分00秒 CST
MacBook-Pro:shell test$ VARDATE=$(date)
MacBook-Pro:shell test$ echo $VARDATE
2018年10月29日 星期一 20时12分14秒 CST
3.6.2 算术代换
  • 概念:通过$(()) 或 $[]实现运算功能。
  • 示例:
MacBook-Pro:shell test$ echo 8 + 2
8 + 2
MacBook-Pro:shell test$ echo $[8 + 2]
10

4. Shell流程控制(判断)

4.1. 条件测试

  • 说明:通过test或 [] 可以测试一个条件是否成立。
  • 语法:

语法:test 值1 条件 值2

语法: [ 值1 条件 值2 ]
脚下留心:0-代表结果成立,1-代表结果不成立;中括号内部两端必须加空格

  • 数值测试:
参数 说明
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-ge 大于等于则为真
-lt 小于则为真
-le 小于等于则为真
  • 文件测试:
参数 说明
-e 文件名 文件存在则为真
-r 文件名 文件存在且可读则为真
-w 文件名 文件存在且可写则为真
-x 文件名 文件存在且可执行则为真
-s 文件名 文件存在且至少有一个字符则为真
-d 文件名 文件存在且为目录则为真
-f 文件名 文件存在且为普通文件则为真
  • 字符串测试:
参数 说明
= 相等则为真
!= 不相等则为真

4.2. if...elif...else语句

  • 语法:

if 条件1
then
    命令1
elif 条件2
then
    命令2
else
    命令3
fi

  • 示例1:判断成绩(>=90优秀,>=80良好,>=60及格,>=0不及格):
#!/bin/bash
#接受分数
SCORE=$1
#判断
if [ $SCORE -ge 90 ]
then
    echo "优秀"
elif [ $SCORE -ge 80 ]
then
    echo "良好"
elif [ $SCORE -ge 60 ]
then
    echo "及格"
elif [ $SCORE -ge 0 ]
then
    echo "不及格"
else
    echo "分数不合法"
fi
  • 示例2:判断当前执行脚本是否是root用户:
#!/bin/bash
WHO=$(whoami)

if [ $WHO != 'root' ]
then
    echo "Error: You must be root to run this script!"  
    exit 1
fi

4.3. case语句

  • 语法:

case $变量名 in
     "值1")
          如果变量的值等于值1,则执行程序1
    ;;
     "值2")
          如果变量的值等于值2,则执行程序2
    ;;
    ....
     *)
         如果以上都不成立,则执行此程序
    ;;
esac

  • 需求:执行脚本让用户输入
    yes - installing...
    no - skip
    其他 - Please enter the correct option
#!/bin/bash

read -p "Please Input yes/no: " Select_Id
case $Select_Id in
  "yes")
    echo 'installing...'
    ;;
  "no")
    echo 'skip'
    ;;
  *)
    echo 'Please enter the correct option'
    ;;
esac

5. Shell循环

5.1 for循环

  • 语法:

for 变量名 in 值1 ... 值N
do
    命令
done

  • 示例1:输出6个数
#!/bin/bash

for i in 1 2 3 4 5 6
do
  echo $i
Done
  • 示例2:输出指定目录下得所有文件名
#!/bin/bash

cd $1
filenames=$(ls)

for name in $filenames
do
   echo $name
done

5.2 while循环

  • 语法:

while 条件
do
    命令
done

  • 示例1:输出1-10
#!/bin/bash

i=1
while [ $i -le 10 ]
do
    echo $i
    i=$(($i+1))
done

6. 计划任务

6.1. 简介

  • 概念:约定时间执行指定任务(或执行指定脚本文件)
  • 举例1:通过计划任务定时发布文章
  • 举例2:通过计划任务凌晨3点将测试服务器项目代码同步到线上服务器

6.2. 使用

  • 步骤1:通过命令【crontab -e】编写计划任务
  • 步骤2:按【i】键编写,最后按【esc】【:wq】保存并退出

多学一招:crontab -e语法同vi编辑器命令 (-e edit缩写)
通过crontab -l 可以查看已有的任务 (-l list缩写)
通过crontab -r 可以移除已有的任务 (-r remove缩写)

6.3. 语法

* * * * * 任务
分 时 日期 月 星期几

项目 含义 范围
第一个“*” 一小时中的第几分钟 0-59
第二个“*” 一天中的第几小时 0-23
第三个“*” 一月中的第几天 1-31
第四个“*” 一年中的第几天 1-12
第五个“*” 一周中的星期几 0-7(0和7代表星期天)
特殊符号 含义
* 代表任何时间。比如第一个“*”就代表一小时中的没分钟都执行一次
, 代表不连续的时间,比如“0 8,12,16 * * *”就代表在每天的8点0分,12点0分,16点0分都执行一次命令
- 代表连续的时间范围。比如“0 5 * * 1-6”代表在周一到周六的凌晨5点0分执行命令
*/n 代表每隔多久执行一次。比如“*/10 * * * *”,代表每隔10分钟就执行一遍命令
  • 例子:每分钟向tmp.txt文件中写入数字6:
*/1  *  *    *   *  echo 9 >> /tmp.txt

其他案例:

   时          间    含义
45 22 * * * 在每天22点45分执行命令
0 17 * * 1 每周1的17点0分执行命令
0 5 1,15 * * 每月1号和15号的凌晨5点0分执行命令
40 4 * * 1-5 每周一到周五的凌晨4点40分执行命令
*/10 4 * * * 每天的凌晨4点,每个10分钟执行一次命令
0 0 1,15 * 1 每月1号和15号,每周一的0点0分执行命令,注意:星期几和几号最好不要同时出现,因为他们定义的都是天,非常容易让管理员混乱
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352