什么是shell
shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
shell对用户输入的命令进行解析,然后传递给Linux内核,因此它被称为命令解释器
将shell从Linux内核分离,避免shell的错误对Linux内核造成影响
第一个shell脚本
1 2
| #!/bin/bash echo 'Hello world'
|
touch
一个bash文件后
1 2
| chomod +x hello.sh ./hello.sh:
|
1 2 3 4
| #!/bin/bahs echo \ 'Hello world' \ 'GOOD'
|
变量
1 2 3 4 5
| #!/bin/bash pen='Hello world' item=pen echo I have a $pem echo I have many ${item}s
|
环境变量
环境变量用于保存一些可以在不修改程序自身代码的情况下,控制命令内部执行的配置参数。
设置环境变量
1 2 3 4 5
| #!/bin/bash
CONFIG_FILE=/root/conf.txt export CONFIG_FILE bash conf.sh
|
在conf.sh中
1 2 3
| #!/bin/bash
echo $CONFIG_FILE
|
特殊的shell变量
位置参数
用于读取命令行参数的变量
1 2 3 4 5 6
| #!/bin/bash echo arg1:$1 echo arg2:$2 echo arg3:$3 echo all:$* echo all:$@
|
特殊参数
变量名 |
说明 |
$# |
位置参数的个数 |
$? |
上一条命令的 |
$$ |
当前进程的进程ID |
$! |
最后启动的后台命令的进程ID |
使用declare声明变量
选项 |
属性 |
-r |
声明只读变量 |
-i |
声明的变量为整型 |
-a |
声明的变量为数组 |
-A |
声明的变量为关联数组 |
数组
1 2 3
| fruite=(apple grape orange peach) list =() declare -a arr1
|
访问数组
1 2 3 4 5 6 7
| $ fruite=(apple grape orange peach) $ echo ${fruite[0]} apple $ echo ${fruite} apple $ echo ${#fruite[@]} 4
|
使用索引进行赋值
1 2 3 4 5 6 7 8 9 10
| #!/bin/bash fruite=(apple [2]=grape [5]=orange [8]=peach) fruite[1]=banana echo num ${#fruite[@]} echo ${fruite[0]} echo ${fruite[1]} echo ${fruite[2]} echo ${fruite[3]} echo ${fruite[4]} echo ${fruite[5]}
|
删除数组
1 2 3 4
| #!/bin/bash fruite=(apple [2]=grape [5]=orange [8]=peach) unset fruite[2] echo ${fruite[@]}
|
访问所有数组
1 2 3 4
| #!/bin/bash fruite=(apple grape orange peach) echo echo ${fruite[@]} echo echo ${fruite[*]}
|
添加元素
1 2 3 4 5 6 7
| #!/bin/bash fruite=(apple grape orange peach) echo ${fruite[@]} fruite=(banana "${fruite[@]}" ) echo ${fruite[@]} fruite=("${fruite[@]}" coco) echo ${fruite[@]}
|
获取元素的索引列表
1 2 3
| #!/bin/bash fruite=(apple grape orange peach) echo ${!fruite[@]}
|
关联数组
一种键值对的数据结构
1 2
| declare -A user user=([id]=2021 [name]=miyake)
|
关联数组必须使用declare进行声明
访问数组元素
1 2 3 4 5
| #!/bin/bash declare -A user=([id]=2021 [name]=harsh) echo ${user[id]} echo ${user[name]} echo ${#user[@]}
|
赋值
1 2 3 4
| #!/bin/bash declare -A user=([id]=2021 [name]=harsh) user[id]=2022 echo ${user[id]}
|
删除
1 2 3
| #!/bin/bash declare -A user=([id]=2021 [name]=harsh) unset user[id]
|
获取所有的值
获取关联数组中的键的列表
展开和引用
路径展开
符号 |
含义 |
? |
任意一个字符 |
* |
任意字符串 |
[ ] |
[ ]中包含的任意一个字符 |
[! ]或[^ ] |
任意一个不在[ ]的字符 |
1 2 3
| ls main.? ls *.sh ls file[1-4].txt
|
大括号展开
{字符串1,字符串2,字符串3}
1
| mkdir work/{src,log,tets}
|
{开始值…结束值}
1 2
| echo file-{8..11}.txt echo file-{8..11..2}.txt
|
波浪线展开
用于指定用户主目录的方法
在字符串~ 用户名
,则展开为指定用户的主目录。如果省略,则展开为当前登录用户的主目录。
参数展开
使用:-
进行展开
:-
根据指定的值是是否被赋值来决定要展开的值
1 2 3 4
| echo ${name:-harsh} name=bill echo ${name:-harsh} echo ${config_file:-$HOME/.conf}
|
历史命令展开
符号 |
说明 |
! |
开始历史记录替换 |
!n |
获取第n条命令行 |
!-n |
获取当前命令往前的第nt条命令 |
!! |
获取上一条命令 |
!string |
获取以string开头的最后执行的命令 |
!?string? |
获取包含string的最后执行的命令 |
^string^string2^ |
将string1替换为string2后重复执行最后的命令 |
!# |
目前输入的所有命令行 |
引用
使用\
进行引用
1 2 3
| echo \* eecho \$ echo \\
|
使用'
和"
进行引用
单引号全部称为字符串
双引号中,$
、\
和`
保留转义
控制结构
If
1 2 3 4 5 6 7
| if 条件;then
elif 条件;then
else
fi
|
1 2 3 4 5 6
| #!/bin/bash if cd "$1";then echo success else echo fail fi
|
test命令
1 2 3
| answer=yes [ "$answer"=yes ] echo $?
|
for
1 2 3 4
| for 变量 in 单词列表 do 循环处理 done
|
case
1 2 3 4 5 6 7 8
| case 字符串 in 模式1) ;; 模式2)
;; esac
|
while
until 命令
do
done
重定向和管道
重定向
输出的重定向
名称 |
文件描述符 |
标准输入 |
0 |
标准输出 |
1 |
标准错误输出 |
2 |
输入的重定向
重定向和追加写入
1 2
| echo line1>>word.txt echo line2>>word.txt
|
标准统一输出和标准输出
1
| ls /usr/xxx >result.txt 2> error.txt
|
将标准输出和标准错误输出定向到同一个文件
1
| ls /usr/xxx >result.txt 2>&1
|
管道
命令分组
1 2 3 4 5 6
| { date +%Y-%m-%d echo '/usr list ' ls /usr } >result.txt {date +%Y-%m-%d;echo '/usr list ';ls /usr;} >result.txt
|
函数
1 2 3 4 5 6 7 8 9
| function 函数名(){ } function 函数名{ } 函数名{ }
|