Shell编程快速入门
权限的基本介绍
我们使用ls -l(ll指令)指令的时候会发现有一串神秘的字符串,其实它就代表了文件的权限。它的每位都有特殊的含义。
我们来看看这9位字符都告诉了我们什么,首先是第0位,它确定了文件的类型,-表示普通文件,i相当于链接,相当于Windows的快捷方式,d是目录,相当于Windows的文件夹,c是字符设备文件,像是鼠标、键盘之类的,b是块设备,比如硬盘。其次1-3位确定所有者拥有该文件的权限,r代表可读,w代表可写,对于目录来讲代表可修改,x表示可执行,对于目录来讲就是可进入。在着4-6位确定所属组拥有该文件的权限。最后7-9确定其他用户拥有该文件的权限。在日期前面还有一些数字,这些数字代表文件大小,至于所有者前面的数字代表硬链接数目,一个文件至少一个,一个文件夹至少两个。在Linux中r可以用4代替,w可以用2代替,x可以用1代替,所以全部的权限可以用7代替。
修改权限chmod指令
基本语法:
chmod u=rwx,g=rx,o=x 文件/目录名
chmod o+w 文件/目录名
chmod a-x 文件/目录名
其中u代表所有者,g代表所在组,o代表其他组,a代表所有,也就是u,g,o的总和。我们可以使用+,-,=变更权限。
也可以用数字变更权限
shell编程
当我们将来走上工作,学会怎么写一个shell脚本是必不可少的,比如我们在进行服务器维护的时候,可能就会需要编写一个脚本来定时备份数据库等等。
shell是什么
知道shell可以做什么了,可是什么是shell呢?shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以通过shell来启动、挂起、停止甚至是编写一些程序。当然Linux不止一个shell,我们常用的是bash。
shell脚本的执行方式
学习shell和我们学习其他语言是一样的我们先来看一下格式的要求,首先脚本要以 #!/bin/bash 开头,其次脚本要有可执行的权限。脚本常用的执行方式有两种,一是要先赋予我们写好的脚本文件x权限,然后输入脚本的绝对路径或相对路径执行,二是使用 sh 脚本这个指令来执行。
shell的变量
之前我们在汇编的学习中提到了,一个有用的程序,多半会存在变量,shell编程也是如此。Linux shell中的变量分为,系统变量和用户自定义变量,系统变量包括$HOME、$PWD、$SHELL、$USER等等,我们可以用set指令显示所有变量。
用户自定义变量的基本语法是:变量名=值,注意在Linux中指令对空格的检测很严格,所以一定要仔细看接下来的指令中是否含有空格,这点很重要!当我们需要删除一个变量的时候我们可以使用指令unset 变量名来进行销毁,我们还可以声明一个静态变量使用指令readonly变量,静态变量不可以被unset销毁掉。当我们输出一个变量的时候我们可以使用指令echo $A,注意$符号,当我们定义变量的时候不需要$但输出的时候需要(tips:#表示注释,多行注释为:<<!……!)。
1 | !/bin/bash |
结果:
在高级语言中,变量的定义是有规则的,在shell编程中也不例外,shell编程中,变量的名称可以由字母、数字和下划线组成,但不能以数字开头,变量定义时等号两边不能有空格,变量名称一般习惯为大写。
当我们希望将一个指令的返回值赋给一个变量,那我们需要使用反引号`(~键)或$()将指令包起来,否则shell认为是将指令本身赋给变量。例如:
1 | !/bin/bash |
结果:
shell字符串
字符串是 shell 编程中最常用最有用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号。
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。而双引号里可以出现变量,而且双引号里面可以含有转义字符。接下来是几个常用的字符串操作:
字符串拼接
1 | #!/bin/bash |
结果:
获取字符串长度
1 | !/bin/bash |
提取字符串
1 | !/bin/bash |
:0:3的意思是从第0位开始截取3个长度的字符。
查找子字符串
1 | !/bin/bash |
设置环境变量
基本语法:export 变量名=变量值,用来将shell变量输出为环境变量(可以理解为全局变量,需要在/etc/profile中定义)
source 配置文件,用来让修改后的配置信息立即生效
echo $变量名,用来查询环境变量的值
1 | vim /etc/profile最下面,如果出现swap交换文件输入e即可 |
结果:
位置参数变量
当我们执行一个shell脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量比如./myshell.sh 100 200,这就是一个执行shell的命令行,可以在myshell中获取到参数信息。
基本语法:
$n,n为数字,0代表命令本身,1-9代表第一个到第九个参数,十以上的参数需要用大括号包含如:${10}。
$*,这个变量表示命令行中所有的参数,它把所有参数看成一个整体。
$@,这个变量也代表命令行中所有参数,不过它把每个参数区分对待。
$#,这个变量表示命令行中所有参数个数,类似高级语言中main函数的变量argc。
1 | !/bin/bash |
结果:
预定义变量
预定义变量是shell设计者已经实现定义好的变量,可以直接在shell脚本中使用,常用的有三个:
- $$,代表当前进程的进程号PID
- $!,代表后天运行的最后一个进程的进程号PID
- $?,代表最后一次执行的命令的返回状态,如果上一个命令正确执行那么返回的值为0,如果这个值非0着表示上一个命令执行不正确,至于错误后返回的到底是多少,由命令自己决定。
1 | !/bin/bash |
结果:
运算符
我们在学习C语言的时候,肯定做过加法减法的程序,当然这也是计算机最基本的操作了,现在我们在shell中看看如何进行运算。
基本语法:
- $((运算式))或$[运算式]或者expr m +(-) n(注意格式)
- 注意运算符间要有空格
- 注意expr中乘法的写法为\*做转义操作
- 在使用expr进行运算时,如果要将计算结果赋值给一个变量,需要将运算式用反引号``括起来
1 | !/bin/bash |
结果:
我们也可以通过之前学习的位置参数变量来优化脚本!
流程控制
我们在编写一个程序的时候,会对一些事情进行判断,如果满足了某一条件,我们就进行一系列操作,反之我们有别的应对,这个时候就要知道流程控制语句。
if语句和if……else语句
基本语法:if [ condition ]then …… fi,如果非空返回true。(注意格式,condition前后都有空格,if和中括号之间也有空格)
if [ condition ]then…… else…… fi,如果非空返回true。
我们在shell编程中常用的判断条件有四类:
1.字符串比较
- =
2.两个整数比较
- -lt 小于
- -le 小于等于
- -eq 等于
- -gt 大于
- -ge 大于等于
- -ne 不等于
3.按照文件权限进行判断
- -r 有读的权限
- -w 有写的权限
- -x 有执行的权限
4.按照文件类型进行判断
- -f 文件存在且是一个常规的文件
- -e 文件存在
- -d 文件存在且是一个目录
1 | !/bin/bash |
结果:
if elif语句
我们已经学会了如何使用if,但有的时候判断会进行很多次,这个时候就要用到了else if,所以我们来看一下shell编程中else if是什么样子的。
基本语法(注意格式):
if [ condition ]then …… fi 或者 if [ condition ]then …… elif [ condition ] then …… fi
注意[ condition ],中括号和condition之间,if和中括号之间,elif和中括号之间必须有空格!!
1 | !/bin/bash |
结果:
case语句
基本语法:
case $变量名 in 值1 )程序1;; 值2)程序2;; 值3)程序3;;…… * )如果变量的值都不是以上的值,执行本程序;; esac
1 | !/bin/bash |
结果:
循环
现在我们需要像屏幕上输出1行hello world,你会选择使用echo hello world完成,如果我们需要输出10条,你可能会使用yy,p来完成,可是如果我们需要输出100条甚至更多呢?这个时候就要使用循环。
for循环
基本语法:
for 变量 in 值1 值2 值3 … do …… done,这里的值1,值2,值3代表一个集合 ,我们可以用省略号代表一个集合,比如1到100就是{1…100}
for (( 初始值;循环控制条件;变量变化 ))do……done
我们这里顺便使用for循环来看一下$*和$@的区别。
1 | !/bin/bash |
结果:
1 | !/bin/bash |
结果:
while循环
基本语法:
while [ 条件判断式 ]do……done,注意while和[之间的空格,条件判断式前后的空格。
1 | !/bin/bash |
结果:
read读取控制台输入
基本语法:read (选项) (参数) 变量,用来读取键盘输入
选项:-p:指定读取值时的提示符
-t:指定读取值时等待的时间(秒),如果没有在指定的时间输入,就不在等待了
1 | !/bin/bash |
结果:
函数
shell编程和其它的编程语言一样有函数的存在,函数可以被分为系统函数和自定义函数,接下来我们就来了解一下。
系统函数
1.基本语法:basename [pathname] [suffix]
basename [string] [suffix]
basename指令会删掉所有的前缀包括最后的一个/字符,然后将字符串显示出来。
选项:suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
结果:
2.基本语法:dirname 文件绝对路径
dirname指令从给定的包含绝对路径的文件名中去除文件名,然后返回剩下来的路径。
结果:
自定义函数
基本语法:
1 | function funname() |
当我们需要调用我们的自定义函数的时候,只需要写函数名即可。
1 | !/bin/bash |
结果:
案例:who_is_up.sh
接下来我们一个案例体验一下shell编程带来的便利。
我们之前使用过ping指令,ping指令会通过发送数据包的形式判断目的主机是否宕机。接下来我们就用这个来看看都有谁在工作:
1 | !/bin/bash |
结果: