什么是shell
shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
shell对用户输入的命令进行解析,然后传递给Linux内核,因此它被称为命令解释器
将shell从Linux内核分离,避免shell的错误对Linux内核造成影响
第一个shell脚本
#!/bin/bash
echo 'Hello world'
touch
一个bash文件后
chomod +x hello.sh # shebang
./hello.sh:
#!/bin/bahs
echo \
'Hello world' \
'GOOD'
变量
变量名=值
#!/bin/bash
pen='Hello world'
item=pen
echo I have a $pem
echo I have many ${item}s
环境变量
环境变量用于保存一些可以在不修改程序自身代码的情况下,控制命令内部执行的配置参数。
设置环境变量
#!/bin/bash
CONFIG_FILE=/root/conf.txt
export CONFIG_FILE
bash conf.sh
在conf.sh中
#!/bin/bash
echo $CONFIG_FILE
特殊的shell变量
- HOME:保存当前登录用户的用户主目录的
- PWD:当前目录
- SHELL:当前登录用户的登录shell的全路径
- BASH:保存了bash命令的全路径
- BASH_VERSION:保持了当前bash命令的版本信息
- LINENO:保存了当前所执行的脚本文件的行号
- LANG:国家语言信息
- PATH:保存了shell启动命令时的目录
- IFS:Internal Field Separator(内部字段分割符)
位置参数
用于读取命令行参数的变量
#!/bin/bash
echo arg1:$1
echo arg2:$2
echo arg3:$3
echo all:$* # 所有参数
echo all:$@ # 所有参数
特殊参数
变量名 |
说明 |
$# |
位置参数的个数 |
$? |
上一条命令的 |
$$ |
当前进程的进程ID |
$! |
最后启动的后台命令的进程ID |
使用declare声明变量
declare var1
选项 |
属性 |
-r |
声明只读变量 |
-i |
声明的变量为整型 |
-a |
声明的变量为数组 |
-A |
声明的变量为关联数组 |
数组
fruite=(apple grape orange peach)
list =() # 空数组
declare -a arr1
访问数组
$ fruite=(apple grape orange peach)
$ echo ${fruite[0]}
apple
$ echo ${fruite} # 默认为0
apple
$ echo ${#fruite[@]} # 获取元素个数
4
使用索引进行赋值
#!/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]}
删除数组
#!/bin/bash
fruite=(apple [2]=grape [5]=orange [8]=peach)
unset fruite[2]
echo ${fruite[@]}
访问所有数组
#!/bin/bash
fruite=(apple grape orange peach)
echo echo ${fruite[@]}
echo echo ${fruite[*]}
添加元素
#!/bin/bash
fruite=(apple grape orange peach)
echo ${fruite[@]}
fruite=(banana "${fruite[@]}" )
echo ${fruite[@]}
fruite=("${fruite[@]}" coco)
echo ${fruite[@]}
获取元素的索引列表
#!/bin/bash
fruite=(apple grape orange peach)
echo ${!fruite[@]}
关联数组
一种键值对的数据结构
declare -A user
user=([id]=2021 [name]=miyake)
关联数组必须使用declare进行声明
访问数组元素
#!/bin/bash
declare -A user=([id]=2021 [name]=harsh)
echo ${user[id]}
echo ${user[name]}
echo ${#user[@]} # 获取个数
赋值
#!/bin/bash
declare -A user=([id]=2021 [name]=harsh)
user[id]=2022
echo ${user[id]}
删除
#!/bin/bash
declare -A user=([id]=2021 [name]=harsh)
unset user[id]
获取所有的值
echo "${fruite[@]}"
获取关联数组中的键的列表
echo "${!fruite[@]}"
展开和引用
路径展开
符号 |
含义 |
? |
任意一个字符 |
* |
任意字符串 |
[ ] |
[ ]中包含的任意一个字符 |
[! ]或[^ ] |
任意一个不在[ ]的字符 |
ls main.?
ls *.sh
ls file[1-4].txt
大括号展开
- {字符串1,字符串2,字符串3}
mkdir work/{src,log,tets}
- {开始值...结束值}
echo file-{8..11}.txt
echo file-{8..11..2}.txt
波浪线展开
用于指定用户主目录的方法
在字符串~ 用户名
,则展开为指定用户的主目录。如果省略,则展开为当前登录用户的主目录。
ls ~
参数展开
ls $HOME
ls ${HOME}
使用:-
进行展开
:-
根据指定的值是是否被赋值来决定要展开的值
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后重复执行最后的命令 |
!# |
目前输入的所有命令行 |
引用
使用\
进行引用
echo \*
eecho \$
echo \\
使用'
和"
进行引用
单引号全部称为字符串
echo '*'
双引号中,$
、\
和`
保留转义