又刷了一遍权游,太好看了!!! (图应该是詹姆单枪刺龙妈)
前言
本文将从helloworld案例开始,逐步介绍shell的语法,并且附上案例,也包括其他的一些知识点。分支循环以及函数部分将在后面篇章介绍。
一、从Helloworld开始
目的: 写一个shell脚本,用于输出Helloworld
步骤
0. 创建一个文件夹用于以后放置shell脚本
mkdir datas
1. 创建一个shell脚本文件
cd datas
touch helloworld.sh
2. 使用vim文本编辑器编辑 helloworld.sh
vim helloworld.sh
3. 文本文件内写上内容
4.执行对应shell脚本
几种实现方式
4.1 sh/bash 文件名
sh helloworld.sh
或者
bash helloworld.sh
4.2 sh/bash 文件绝对路径
bash /home/datas/helloworld.sh
或者
sh /home/datas/helloworld.sh
4.3 直接调用对应shell脚本
./helloworld.sh
4.3.1 权限不够怎么办
原因:如果使用sh/bash,就是让编译器去帮我们执行,编译器是有这个权限的。 如果我们自己直接去调用可能会权限不足。
查看一下我们对这个文件的权限
ll helloworld.sh
文件信息前面表示
解决: 给予当前用户执行权限,详细可见下面知识点内容。
由于我们当前用户就是文件属主,所以直接给予属主权限即可
第一种方式:使用数字赋予权限
chmod 764 helloworld.sh
第二种方式:使用符号赋予权限
chmod u=rwx,g=rw,o=r helloworld.sh
二、多命令的shell脚本
写了helloworld之后,多命令也非常容易理解
目标: 在/home/hjw/下创建一个文本,文本中写入一段话 fire and blood"(最近在刷龙之家族,权游系列太好看了!!/(ㄒoㄒ)/~~)
1. 直接新建shell脚本如下
然后执行即可得到对应结果
三、系统变量以及自定义变量
1. 常见系统变量
| 系统变量 | 含义 | 用途 |
|---|---|---|
| $HOME | 家目录 | 用于找到当前用户的家目录 |
| $PWD | 目前所在位置 | 用于找到当前位置 |
| $SHELL | 默认解析器 | 找到默认解析器 |
| $USER | 当前用户 | 一般用于输出当前用户是谁 |
2. 自定义变量
2.1 基本语法
- 定义变量:
变量=赋值。(等号左右是没有空格的!!!) - 使用变量:
$变量名 或${变量名} - 取消变量:
unset 变量。 - 定义静态变量:
readonly 变量=赋值。(静态变量不可修改,不可unset) - 将变量设置为全局有效:
export 变量。
unset 和 readonly 实现如下
使用变量时,加与不加大括号的区别
当我们需要边界时,比如需要进行字符串拼接时
do my $homework 和 do my ${home}work是不同的,前者认为homework是一个变量,后者认为home是一个变量。
2.2 变量名定义规则
变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线 _。
- 不能使用标点符号。
- 不能使用bash里的关键字(可用help命令查看保留关键字)。
- 环境变量名建议大写
有效的 Shell 变量名示例如下:
RUNOOB
LD_LIBRARY_PATH
_var
var2
无效的变量命名:
?var=123
user*name=runoob
3.变量数据类型
3.1 字符串
- bash中默认的数据类型是字符串,所以无法进行运算。
- 对于含有空格的字符串,需要使用单引号或者双引号括起来。
- 可以使用 单引号和双引号区别
单引号:无法使用变量只会原样输出,单引号必须成对出现,转义单引号也不行。
双引号:可以使用变量,可以使用转义字符。
3.2 数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
类似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。
3.2.1 定义数组
在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
数组名=(值1 值2 ... 值n)
例如:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
还可以单独定义数组的各个分量:
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
可以不使用连续的下标,而且下标的范围没有限制。
3.2.2读取数组
读取数组元素值的一般格式是:
${数组名[下标]}
例如:
valuen=${array_name[n]}
使用 @ 符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}
3.2.3获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
实例
取得数组元素的个数
length=${#array_name[@]}
或者
length=${#array_name[*]}
取得数组单个元素的长度
lengthn=${#array_name[n]}
3.2.4示例
4.特殊变量
4.1特殊变量 $n
$n含义:
- n表示一个数字.
$0表示当前文件名称$1到$9表示脚本中第1到9 对应的参数- 十以上需要使用大括号如
${10},也表示对应参数
参数一般用于输入到脚本中
案例: 输出输入的三个参数
- 编写脚本
- 执行脚本并且输入参数
结果如上,只会输出文件名 和 前三个参数,多的不会输出,少的也不会输出
4.2特殊变量 $#
$#含义: 用于获取参数个数,一般用在循环中
1.稍作修改shell脚本
2.执行脚本
4.3特殊变量 $* 、 $@
$*:表示代表命令行中所有参数,并且当作一个整体看待。
$@:表示代表命令行中所有参数,但是区分看待。
直接输出两者没有任何差别,但是获取方式不同,会在分支循环中使用到。
案例
4.4特殊变量 $?
$?:用于表明上一条命令是否正确执行
正确执行会是0
不正确会是1
四、运算符
前面说到,bash中默认的变量都是字符串,如果要进行运算怎么办? 以及一一些逻辑判断是咋写的?
1. 算数运算符
算数运算符用于数值计算,比如加减乘除取余等操作
1.1 语法
$((运算式)) 或者$[运算式]-expr +, -, \*, /, %, 加 减 乘 除 取余。- -
注意 :乘法是 \*, 符号左右需要有空格
1.2 示例
复杂语句怎么办? 比如 (2+3)*4
- 直接
expr ``expr 2 + 3 ``\* 4
- 使用括号方式
注意:这里的是直接*,而不是 \*
2. 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字
2.1 语法
| 运算符 | 说明 |
|---|---|
| -eq | 判断两个数是否相等,相等返回true |
| -ne | 判断两个数不相等,不相等返回true |
| -gt | 相当于大于号,如果左边大于右边返回true |
| -lt | 相当于小于号,右边大于左边返回true |
| -ge | 大于等于号,如果左边大于等于右边,返回true |
| -le | 小于等于号, 如果左边小于等于右边返回true |
以上内容,如果不满足条件则为false |
2.2 示例
这里写一个简单的示例,本来想用命令行来写。但是没找到合适的方法,于是就写一个shell脚本。 里面用到了后面的if判断语句,后面会介绍到。
3. 逻辑运算符
| 运算符 | 说明 |
|---|---|
| && | 逻辑的与 AND |
| | | | 逻辑的或 OR |
3.2示例
注意:当有两个表达式时,是两层中括号
4. 布尔运算符
| 运算符 | 说明 |
|---|---|
| ! | 非运算,相当于取反 |
| -o | 或运算, 有一个表达式为true 则为true |
| -a | 与运算,表达式必须都为true,才为true |
5. 字符串运算符
5.1 语法
| 运算符 | 说明 |
|---|---|
| = | 检测两个字符串是否相等,相等返回true |
| != | 检测俩字符串是否不相等,不相等返回true |
| -z | 检测字符串长度是否为0,为0返回true |
| -n | 检测字符串长度是否为0, 不为0返回true |
| str | 检测字符串是否为空,不为空返回true |
5.2 示例
6. 文件运算符
这里其实可以说是操作符
6.1 语法
| 操作符 | 说明 |
|---|---|
| -b file | 检测文件是否是块设备文件,如果是,返回true |
| -c file | 检测文件是否是字符设备文件,如果是,返回true |
| -d file | 检测文件是否是目录, 如果是,返回true |
| -f file | 检测文件是否是普通文件(不是目录也不是设备文件)如果是,返回true |
| -g file | 检测文件是否设置了 SGID位,如果是,则返回 true |
| -k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,返回true |
| -p file | 检测文件是否是有名管道,如果是,则返回true |
| -u file | 检测文件是否设置了SUID位,如果是, 返回true |
| -r file | 检测文件是否可读,如果是,则返回true |
| -w file | 检测文件是否可写,如果是,则返回true |
| -x file | 检测文件是否可执行, 如果是,则返回true |
| -s file | 检测文件是否为空(文件发小是否大于零)不为空返回true |
| -e file | 检测文件(包括目录)是否存在,如果是,则返回true |
使用起来比较简单
6.2示例
比较简单,将上面的例子改一下就好
遇到的问题
1. 在写布尔运算符示例时,总是报错"参数太多"
脚本如下
执行结果如下
原因:
当变量中有空格时,就会导致bash识别时造成误会。他会直接将对应变量值放在这个地方,因为
存在空格,导致变量中每一个单词都被认为是一个单独的参数。
解决一:去掉变量中的空格
亲测成功,但是会导致我们的代码不符合目的
解决二:将变量加上双引号
亲测成功。
知识点
以下内容用于复习Linux相关知识点,与shell无关。
1. Linux的文件权限查看以及权限赋予
1.1 权限查看
在 Linux 中我们可以使用 ll 或者 ls –l 命令来显示一个文件的属性以及文件所属的用户和组,如:
[root@www /]# ls -l
total 64
dr-xr-xr-x 2 root root 4096 Dec 14 2012 bin
dr-xr-xr-x 4 root root 4096 Apr 19 2012 boot
……
实例中,bin 文件的第一个属性用 d 表示。d 在 Linux 中代表该文件是一个目录文件。
在 Linux 中第一个字符代表这个文件是目录、文件或链接文件等等。
- 当为 d 则是目录
- 当为 - 则是文件;
- 若是 l 则表示为链接文档(link file);
- 若是 b 则表示为装置文件里面的可供储存的接口设备(可随机存取装置);
- 若是 c 则表示为装置文件里面的串行端口设备,例如键盘、鼠标(一次性读取装置)。
接下来的字符中,以三个为一组,且均为 rwx 的三个参数的组合。其中, r 代表可读(read)、 w 代表可写(write)、 x 代表可执行(execute)。 要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号 - 而已。
每个文件的属性由左边第一部分的 10 个字符来确定(如下图)。
从左至右用 0-9 这些数字来表示。
第 0 位确定文件类型,第 1-3 位确定属主(该文件的所有者)拥有该文件的权限。
第4-6位确定属组(所有者的同组用户)拥有该文件的权限,第7-9位确定其他用户拥有该文件的权限。
其中,第 1、4、7 位表示读权限,如果用 r 字符表示,则有读权限,如果用 - 字符表示,则没有读权限;
第 2、5、8 位表示写权限,如果用 w 字符表示,则有写权限,如果用 - 字符表示没有写权限;第 3、6、9 位表示可执行权限,如果用 x 字符表示,则有执行权限,如果用 - 字符表示,则没有执行权限。
1.2 权限赋予
chmod:更改文件9个属性
Linux文件属性有两种设置方法,一种是数字,一种是符号。
Linux 文件的基本权限就有九个,分别是 owner/group/others(拥有者/组/其他) 三种身份各有自己的 read/write/execute 权限。
先复习一下刚刚上面提到的数据:文件的权限字符为: -rwxrwxrwx , 这九个权限是三个三个一组的!其中,我们可以使用数字来代表各个权限,各权限的分数对照表如下:
- r:4
- w:2
- x:1
每种身份(owner/group/others)各自的三个权限(r/w/x)分数是需要累加的,例如当权限为: -rwxrwx--- 分数则是:
- owner = rwx = 4+2+1 = 7
- group = rwx = 4+2+1 = 7
- others= --- = 0+0+0 = 0
所以等一下我们设定权限的变更时,该文件的权限数字就是 770。变更权限的指令 chmod 的语法是这样的:
chmod [-R] xyz 文件或目录
选项与参数:
- xyz : 就是刚刚提到的数字类型的权限属性,为 rwx 属性数值的相加。
- -R : 进行递归(recursive)的持续变更,以及连同次目录下的所有文件都会变更
举例来说,如果要将 .bashrc 这个文件所有的权限都设定启用,那么命令如下:
[root@www ~]# ls -al .bashrc
-rw-r--r-- 1 root root 395 Jul 4 11:45 .bashrc
[root@www ~]# chmod 777 .bashrc
[root@www ~]# ls -al .bashrc
-rwxrwxrwx 1 root root 395 Jul 4 11:45 .bashrc
那如果要将权限变成 -rwxr-xr-- 呢?那么权限的分数就成为 [4+2+1][4+0+1][4+0+0]=754。
符号类型改变文件权限
还有一个改变权限的方法,从之前的介绍中我们可以发现,基本上就九个权限分别是:
- user:用户
- group:组
- others:其他
那么我们就可以使用 u, g, o 来代表三种身份的权限。
此外, a 则代表 all,即全部的身份。读写的权限可以写成 r, w, x,也就是可以使用下表的方式来看:
| chmod | u g o a | +(加入) -(除去) =(设定) | r w x | 文件或目录 |
|---|
如果我们需要将文件权限设置为 -rwxr-xr-- ,可以使用 chmod u=rwx,g=rx,o=r 文件名 来设定:
# touch test1 // 创建 test1 文件
# ls -al test1 // 查看 test1 默认权限
-rw-r--r-- 1 root root 0 Nov 15 10:32 test1
# chmod u=rwx,g=rx,o=r test1 // 修改 test1 权限
# ls -al test1
-rwxr-xr-- 1 root root 0 Nov 15 10:32 test1
而如果是要将权限去掉而不改变其他已存在的权限呢?例如要拿掉全部人的可执行权限,则:
# chmod a-x test1
# ls -al test1
-rw-r--r-- 1 root root 0 Nov 15 10:32 test1
1.3 chgrp:更改文件属组
语法:
chgrp [-R] 属组名 文件名
参数选项
- -R:递归更改文件属组,就是在更改某个目录文件的属组时,如果加上-R的参数,那么该目录下的所有文件的属组都会更改。
1.4、chown:更改文件属主,也可以同时更改文件属组
语法:
chown [–R] 属主名 文件名
chown [-R] 属主名:属组名 文件名
进入 /root 目录(~)将install.log的拥有者改为bin这个账号:
[root@www ~] cd ~
[root@www ~]# chown bin install.log
[root@www ~]# ls -l
-rw-r--r-- 1 bin users 68495 Jun 25 08:53 install.log
将install.log的拥有者与群组改回为root:
[root@www ~]# chown root:root install.log
[root@www ~]# ls -l
-rw-r--r-- 1 root root 68495 Jun 25 08:53 install.log
以上实践以及笔记内容皆为原创,知识点内容部分来自于网络,如有不足或者错误,请评论区或者私信指正。