学习笔记,记录以下课程中关于Linux的Shell基础知识。
目录
1.编写规范
1)代码规范:
# !/bin/bash 文件首行,指定告知系统当前这个脚本要使用的shell解释器
2)文件命名规范:
文件名.sh .sh是Linux下bash shell 的默认后缀
使用流程:
1)创建.sh文件 touch/vim
2)编写shell代码
3)为文件添加执行权限 chmod +x 文件
4)执行shell脚本
方法1:文件的绝对路径或相对路径
方法2:/bin/bash 文件名 含义:直接运行解释器,其参数就是 shell 脚本的文件名
示例1:
创建test.sh,实现第一个shell脚本程序,输出hello world
1)创建文件
vim test.sh
2)编写代码
#!/bin/bash
echo "hello world"
【注】输出的内容如果包括字母和符号(不包含变量),则需要用引号括起来。
3)为文件添加执行权限
chmod +x test.sh
4)执行shell脚本
./test.sh
注意,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。
示例2:
使用root用户账号创建并执行test1.sh,实现创建一个shelltest用户,并在其家目录中新建try.html
创建文件
vim test1.sh
编辑
#!/bin/bash
useradd shelltest;
touch /home/shelltest/try.html
权限
chmod +x test1.sh
执行文件
/bin/bash test1.sh 或cd到文件目录,执行./test1.sh
2.变量
2.1 变量的含义
在一个脚本周期内,其值可以发生改变的量就是变量。其中脚本周期可以简单理解为当前的shell文件。
2.2 变量的定义和使用
定义形如:class_name="star"
使用形如:echo $class_name
变量名的规范
注意,变量名后面的等号不能有空格 ,
变量的命名规则如下:
- 只能使用英文字母,数字和下划线
- 不能以数字开头
- 不能使用bash中的关键字(可用help命令查看保留关键字)
示例1:定义一个变量为hello world并输出
创建文件
vim test2.sh
编辑
#!/bin/bash
str="hello world"
echo $str
权限
chmod +x test2.sh
执行
./test2.sh
关于单双引号的问题:
双引号能够识别变量,双引号能够实现转义(类似于“\*”)
单引号是不能识别变量,只会原样输出,单引号是不能转义的
示例2:定义一个变量输出当前时间,要求格式为“年-月-日 时:分:秒”
创建文件
vim test3.sh
编辑
#!/bin/bash
time=`date -d +"%Y %m %d %H:%M%S"`
echo $time
权限
chmod +x test3.sh
执行
./test3.sh
【注】反引号`(Esc下方的那个键),当在脚本中需要执行一些指令并且将执行的结果赋给变量的时候需要使用“反引号”。
2.3 只读变量(了解)
语法:readonly 变量名
示例:定义变量a并且其值为10,随后设置为只读变量,再去尝试重新赋值
创建文件
vim test4.sh
编写脚本
#!/bin/bash
a=10
readonly a
a=20
echo $a
权限
chmod +x test4.sh
执行
./test4.sh
2.4 接收用户输入(重点)
语法:read -p 提示信息 变量名
示例: 提示用户输入文件路径并创建。
#! /bin/bash
read -p '请输入需要创建的文件路径:' filepath
touch $filepath
echo '创建文件成功!'
ls -l $filepath
执行文件
2.5 删除变量(了解)
语法:unset 变量名
示例:定义变量b=20,再输出b的值,随后删除b ,最后再输出下b
#!/bin/bash
b=20
echo $b
unset b
echo $b
3.运算符
3.1 算数运算符
下表列出了常用的算数运算符,假定变量a为10,变量b为20:
运算符 | 说明 | 举例 |
+ | 加法 | `expr $a + $b` 结果为30 |
- | 减法 | `expr $a - $b` 结果为-10 |
* | 乘法 | `expr $a \* $b` 结果为200 |
/ | 除法 | `expr $b / $a` 结果为2 |
% | 取余 | `expr $b $a` 结果为0 |
= | 赋值 | a=$b 将变量b的值赋给a |
== | 相等,相等返回true | [ $a == $b ] 返回false |
!= | 不等,不等返回true | [ $a != $b ] 返回true |
注意:条件表达式要放在方括号之间,并且要有空格,例如:[$a==$b]是错误的,必须写成
[ $a == $b ]
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr(常用)。
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
例如,两个数相加(注意使用的是反引号 ` 而不是单引号 ' ):
#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为:$val"
注意两点:
表达式和运算符之间要有空格,例如 2+2 是错误写法,必须写成 2 + 2。
完整的表达式要被反引号``包含,注意这个字符不是单引号',它在Esc键下边。
#!/bin/bash
#两个变量的初始化赋值
a=0
b=20
echo "a=$a"
echo "b=$b"
echo ''
echo 'a + b = ' expr $a + $b
echo 'a - b = ' expr $a - $b
echo 'a * b = ' expr $a \* $b
echo 'b / a = ' expr $b / $a
echo 'b % a = ' expr $b % $a
if [ $a == $b ]
then
echo 'a等于b'
else
echo 'a不等于b'
fi
3.2 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量a为10,变量b为20。
运算符 | 说明 | 举例 |
-eq | equal,检测两个数是否相等,相等返回true | [ $a -eq $b ] 返回 false |
-ne | not equal,检测两个数是否相等,不相等返回true | [ $a -ne $b ] 返回true |
-gt | great than,检测左边的数是否大于右边的, 如果是,则返回true |
[ $a -gt $ $b ] 返回false |
-lt | less than,检测左边的数是否大于右边的, 如果是,则返回true |
[ $a -lt $b ] 返回true |
-ge | great than or equal ,检测左边的数是否大于等于右边的,如果是,则返回true | [ $a -ge $b ] 返回false |
-le | less than or equal,检测左边的数是否小于等于右边的,如果是,则返回true | [ $a -le $b ] 返回true |
示例
进行简单的比较
#!/bin/bash
a=10
b=20
echo "a = $a"
echo "b = $b"
#无输出内容,则输出空白行
echo
#判断a与b的关系
if [ $a -eq $b ]
then
echo 'a = b'
elif [ $a -gt $b ]
then
echo 'a > b'
else
echo 'a < b'
fi
写一个脚本,判断当前输入的用户是否存在,如果存在则提示“用户存在”否则提示“用户不存在”
#!/bin/bash
read -p '请输入所要查询的用户名:' username
count=`cat /etc/passwd | grep $username | wc -l `
if [ $count -gt 0 ]
then
echo '该用户存在'
else
echo '该用户不存在'
fi
3.3 逻辑运算符
下表列出了常用的布尔运算符,假定变量a为10,变量b为20:
运算符 | 说明 | 举例 |
! | 非运算, 表达式为 真 则返回false,否则返回true |
[ ! false ] 返回 true |
-o | or,或运算, 有一个表达式为真,则返回true |
[ $a -lt 20 -o &b -gt 30] 返回true |
-a | and,与运算, 全部表达式为真,才返回true |
[ $a -lt 20 -o &b -gt 30] 返回fals |
#!/bin/bash
a=10
b=20
if [ !false ]
then
echo '真'
fi
#或运算
if [ $a -lt 20 -o $b -gt 30 ]
then
echo '真'
else
echo '假'
#与运算
if [ $a -lt 20 -a $b -gt 30 ]
then
echo '真'
else
echo '假'
3.4 字符串运算符
下表列出了常用的字符串运算符,假定变量a为“abc”,变量b为“efg”
运算符 | 说明 | 举例 |
= | 两个字符串是否相等,相等返回true | [ $a = $b ] 返回 false |
!= | 两个字符串是否相等,不相等返回true | [ $a != $b ] 返回 true |
-z | 检测字符串长度是否为0,为0返回 true | [ -z $a ] 返回 false |
-n | 检测字符串长度是否为0,不为0返回 true | [ -n $a ] 返回 true |
str | 检测字符串是否为空,不为空返回 true | [ $a ] 返回 true |
#!/bin/bash
a=abc
b=efg
if [ $a != $b ]
then
echo 'true'
else
echo 'false'
fi
if [ -z $a ]
then
echo 'true'
else
echo 'false'
fi
3.5 文件测试运算符
文件测试运算符用于检测 Unix/Linux 文件的各种属性。
属性检测描述如下:
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否块设备文件, 如果是,则返回true |
[ -b $file ] 返回 false |
-c file | 检测文件是否是文字设备文件, 如果是,则返回true |
[ -c $file ] 返回 false |
-d file | 检测文件是否是字符设备文件, 如果是,则返回true |
[ -d $file ] 返回 false |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件)。 如果是,则返回 true |
[ -f $file ] 返回 true |
-q file | 检测文件是否设置了 SGID 位, 如果是,则返回 true |
[ -q $file ] 返回 false |
-k file | 检测文件是否设置了黏着位(Sticky Bit ) 如果是,则返回 true |
[ -k $file ] 返回 false |
-p file | 检测文件是否有名管道, 如果是,则返回 true |
[ -p $file ] 返回 false |
-u file | 检测文件是否设置了 SUID 位, 如果是,则返回 true |
[ -u $file ] 返回 false |
-r file | 检测文件是否可读, 如果是,则返回 true |
[ -r $file ] 返回 true |
-w file | 检测文件是否可写, 如果是,则返回 true |
[ -w $file ] 返回 true |
-x file | 检测文件是否可执行, 如果是,则返回 true |
[ -x $file ] 返回 true |
-s file | 检测文件是否为空(文件大小是否大于0) 不为空返回 true |
[ -s $file] |
-e file | 检测文件(包括目录)是否存在, 如果是,则返回true |
[ -e $file ] 返回 true |
示例:测试上述标绿的语法
#!/bin/bash
#定义文件的路径
filepath='/root/sss.txt'
#判断是否是目录
if [ -d $filepath ]
then
echo '是目录'
else
echo '不是目录'
fi
#判断是否是具有可读权限
if [ -r $filepath ]
then
echo '可读'
else
echo '不可读'
fi
使用-e运算符,改写“1.4 接收用户输入” 的案例,在创建文件的时候需要先判断是否存在,如果存在则提示用户并且不执行创建操作,如果不存在则创建。
#!/bin/bash
read -p '请输入需要创建的文件名称:' filepath
if [ -e $filepath ]
then
echo '该文件已存在'
else
touch $filepath
echo '创建成功!'
fi
4.控制语句
4.1 条件判断语句
if语句
语法1(一个条件):
if condition
then
command1
command2
...
fi
单行写法:
if [condition];then command;fi
语法2(两个条件):
if condition
then
command1
command2
...
else
command
fi
语法3(多个条件) :
if condition1
then
command1
elif conditon2
then
command2
else
commandN
fi
case语句
case expression in
pattern1)
commands
;;
pattern2)
commands
;;
...
esac
实现加减乘除
read -p "请输入第一个操作数:" num1
read -p "请输入操作符(+、-、*、/):" operator
read -p "请输入第二个操作数:" num2
case $operator in
"+")
result=$(($num1+$num2))
echo "计算结果为:$result"
;;
"-")
result=$(($num1-$num2))
echo "计算结果为:$result"
;;
"")
result=$(($num1*$num2))
echo "计算结果为:$result"
;;
"/")
result=$(($num1/$num2))
echo "计算结果为:$result"
;;
*)
echo "输入的操作符有误!"
;;
esac
4.2 循环语句
1)for
for var in list
do
commands
done
输出1到10
for i in {1..10}
do
echo $i
done
2)while
while condition
do
commands
done
输出1到10
i=1
while [ $i -le 10 ]
do
echo $i
i=$(($i+1))
done
5.shell脚本附带选项(重点)
这个功能可以简单理解为函数传参 ,利用脚本文件中的 $序号 ,可以接收外部参数。
例如:
传递:
./test.sh a b c
接收:
在脚本中可以用“$1”来表示 a ;
“$2”来表示 b ,以此类推。
接收可以用“$”加上选项对应的序号即可。
示例:
1.编写test.sh,传递a,b,c,输出其值。
#!/bin/bash
echo $1 $2 $3
2.创建自定义指令“user”,可以直接执行, 要求该指令具备以下语法和功能:
a.user -add 用户名 【添加用户】
b.user -del 用户名 【删除用户及其家目录】
脚本文件编辑
#!/bin/bash
if [ $1 = '-add' ]
then
useradd $2
elif [ $1 = '-del' ]
then
userdel -r $2
else
echo "命令输入错误"
fi
修改自启动文件,给该脚本文件设置别名,让执行该脚本像指令一样执行。
vim ~/.bashrc
重新执行刚修改的文件
source .bashrc
测试命令:
user -add abc
使用命令 cat /etc/passwd ,可查看用户信息