shell简单入门教程
shell 入门
- 脚本格式
#!/bin/bash
- 第一个shell脚本
- 创建一个shell脚本,输出 hello world
- 示例
#!/bin/bash
echo "hello world"
- 脚本常用的执行方式
sh test.sh
bash test.sh
./test.sh
source test.sh
系统变量
- 系统变量
$HOME # 获取家目录地址
$PWD # 获取当前的路径
$SHELL # 获取当前使用的shell解释器
自定义变量规则
- 变量名可以由字符、数字和下划线组成, 但是不能以数字开头,环境变量建议大写。
- 等号的两侧不能有
空格
- bash中默认的变量都是字符串类型,所以无法直接进行数值运算。
- 变量的值如果有空格,需要使用双引号或者单引号括起来。
- 声明变量
注意:等号的左右时没有空格的
# 声明变量 A 和 B
A=1
B=2
- 获取变量
使用 $ 符号
# 获取变量
$A
$B
- 声明静态变量
readonly
静态变量,只能读取,不能进行重新赋值和删除
# 声明静态变量
readonly C=1
# 读取静态变量
echo $C
特殊变量
- ${n}
n 为数字,$0 代表脚本名称,$1代表第一个参数,依此类推。
如果参数的个数超过9个,则需要加
{}
,例如 ${10}
#!/bin/bash
echo "$0 $1 $2 $3"
./test.py 1 2 3
- $#
获取传入参数的个数, 一般用于循环
#!/bin/bash
echo "参数的个数:"$#
./test.py 1 2 3 4 5 6 7 8
- $*
获取命令行中的所有的参数,会把所有的参数当成一个整体
#!/bin/bash
echo $*
- $@
获取命令行中的所有的参数,但会将参数区别对待
#!/bin/bash
echo $@
- $?
最后一次执行命令的返回状态,这个变量值为0,证明上一次执行的命令是正确的,如果这个值为非0,则证明上一次执行的命令是错误的。
#!/bin/bash
cat ./b.txt
echo $?
运算符
- 基本语法
$((运算表达式))
或者$[运算表达式]
expr +(加法),-(减法),\*(乘法),/(除法),%(取余),expr 运算符间有空格
- 示例
- 计算 3+2的值
```shell
root@win:~# expr 2 + 3
5
```
- 计算 3-2的值
```shell
root@win:~# expr 3 - 2
1
```
- 计算 (2+3)*4的值
```shell
root@win:~# expr `expr 2 + 3` \* 4
20
```
- 使用 $ 计算, 使用
()
需要有至少两层,例如$((表达式))
```shell
root@win:~# echo $(((2+3)*4))
20
root@win:~# echo $[2+3]
5
```
条件判断
- 基本语法
- 语法
```shell
[ condition ]
```
- 注意事项
1. 条件前后要有空格,条件为空则为false, 否则为true
- 比较符号
=
字符串等于-lt
小于-gt
大于-eq
等于-le
小于等于-ge
大于等于-ne
不等于- 示例
```shell
# 判断 23 大于等于 22
root@win:~# [ 23 -ge 22 ]
root@win:~# echo $?
0
# 判断 23 大于等于 24
root@win:~# [ 23 -ge 24 ]
root@win:~# echo $?
1
```
- 按照文件权限进行判断
-r
有读的权限-w
有写的权限-x
有执行的权限- 示例
```shell
# 查看文件
qiang@win:~$ ll
-rw-rw-rw- 1 qiang qiang 0 Jul 11 15:37 a.txt
-rwxr-xr-x 1 root root 34 Jul 11 09:54 helloworld.sh*
# 判断 helloworld.sh 是否有读的权限(有)
qiang@win:~$ [ -r helloworld.sh ]
qiang@win:~$ echo $?
0
# 判断 a.txt 是否有执行的权限(无)
qiang@win:~$ [ -x a.txt ]
qiang@win:~$ echo $?
1
```
- 按照文件类型进行判断
-f
文件存在,并且是一个常规的文件-e
文件存在-d
目录存在- 示例
```shell
# 判断一个文件是否存在 (存在)
qiang@win:~$ [ -f a.txt ]
qiang@win:~$ echo $?
0
# 判断一个文件是否存在 (不存在)
qiang@win:~$ [ -f b.txt ]
qiang@win:~$ echo $?
# 判断b.txt是一个目录 (不是)
qiang@win:~$ [ -d b.txt ]
qiang@win:~$ echo $?
1
# 创建目录c并且判断c 是一个目录(是)
qiang@win:~$ mkdir c
qiang@win:~$ [ -d c ]
qiang@win:~$ echo $?
0
```
- 多条件判断
&&
表示前一条命令执行成功时,才执行后一条命令,如果前一条命令执行失败,则后面命令不会执行。||
表示前一条命令执行成功时,就不会执行后一条命令。如果前一条命令执行失败,才会执行后一条命令- 示例
```shell
# 判断22大于21为真,然后echo ok为真, 不执行或语句
qiang@win:~$ [ 22 -gt 21 ] && echo ok || echo success
ok
# 判断22大于21为假,不执行echo ok语句, 执行或语句,输出 success
qiang@win:~$ [ 22 -gt 23 ] && echo ok || echo success
success
```
条件分支
if
语句
- 基本语法
```shell
# 第一种方式
if [ 条件表达式 ];then
程序
fi
# 第二种方式
if [ 条件表达式 ]
then
程序
fi
```
- 示例
```shell
#!/bin/bash
if [ $1 -eq 1 ]
then
echo "输入的参数是1"
elif [ $1 -eq 2 ]
then
echo "输入的参数是2"
else
echo "输入错误"
fi
```
```shell
#!/bin/bash
if [ $1 -eq 1 ];then
echo "输入的参数是1"
elif [ $1 -eq 2 ];then
echo "输入的参数是2"
else
echo "输入的参数有误"
fi
```
- 注意事项
1. \[ 条件表达式 \] ,中括号与条件表达式中间必须有空格
2. 要有 `fi` 结尾
case
语句
- 基本语法
```shell
case
```
- 注意事项
1. `case` 行结尾为单词 `in` , 每一个模式匹配符必须以`)` 结束。
2. `1)` 里面的值最好是字符串类型。
3. 双分号`;;` 表示命令序列结束。相当于 `break`
4. `*)` 表示默认模式,相当于 `default`
5. 默认模式 `;;` 可写可不写,推荐 写
- 示例
```shell
#!/bin/bash
case $1 in
"1")
echo "python"
;;
"2")
echo "java"
;;
"h")
echo "h"
;;
*)
echo "others"
;;
esac
```
循环语句
for
循环
- 基本语法
```shell
for ((初始值; 循环控制条件;步长))
do
程序
done
for 变量 in 值1 值2 值3
do
程序
done
```
- 注意事项
1. `for(())` 要有两个括号
2. 程序需要在 `do` 和 `done` 之间
- 示例
```shell
#!/bin/bash
# 计算1到100的和
sum=0
for ((i=1;i<=100;i++))
do
sum=$(($sum+$i))
done
echo $sum
#!/bin/bash
# 获取参数并打印,$@和$*效果是一样的
for i in $@
do
echo $i
done
for i in $*
do
echo $i
done
# 获取参数并打印,“$@”和“$*”效果是不一样的
# "$@" 和上面的是一样的,也是分别打印
# "$*" 和上面的不一样了,他是作为一个整体输出的
for i in “$@”
do
echo $i
done
for i in “$*”
do
echo $i
done
```
while
循环
- 基本语法
```shell
while [ 条件表达式 ]
do
程序
done
```
- 注意事项
1. 条件表达式两边需要有空格
2. 程序必须在 `do` 和 `done` 中间
3. 程序必须有限制条件,否则会造成死循环
- 示例
```shell
#!/bin/bash
# 计算1加到100的和
i=1
sum=0
while [ $i -le 100 ]
do
# 累加的和
sum=$[$sum+$i]
# 限制条件
i=$[$i+1]
done
echo $sum
```
读取控制台的输入
read
- 基本语法
```shell
read -t 读取数据的时间 -p "提示语句" 接收数据的变量
```
- 注意事项
1. `-p` 指定读取值的提示符
2. `-t` 指定读取时等待的时间,默认单位秒。如果超出时间,则退出程序
3. 需要有一个接收数据的变量
- 案例
```shell
#!/bin/bash
# 20s 内输入数据,用Name来接收数据,并打印
read -t 20 -p "input your name" Name
echo $Name
```
函数
- 系统函数
basename
> 功能:获取文件的名称
```shell
# 获取文件名称
qiang@win:~$ basename /home/qiang/case.sh
case.sh
# 获取文件名称,不带后缀
qiang@win:~$ basename /home/qiang/case.sh .sh
case
```
dirname
> 功能: 获取文件的绝对路径
```shell
# 获取文件的绝对路径
qiang@win:~$ dirname /home/qiang/case.sh
/home/qiang
```
- 自定义函数
- 基本语法
```shell
[function] funcname[()]
{
程序
[return int;]
}
funcname
```
- 注意事项
1. 先声明函数,然后才可以调用
2. 函数的返回值,只能使用`$?` 来调用,可以显示条件`return int`,如果不加,则默认最后条命令执行的结果作为返回值。 return返回值的范围在0~255之间
- 示例
```shell
#!/bin/bash
# 定义求和函数
function add()
{
sum=$[$1+$2]
echo $sum
}
read -p "请输入第一个参数: " p1
read -p "请输入第二个参数: " p2
add $p1 $p2
```