0%

shell脚本学习笔记

什么是shell

shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

shell对用户输入的命令进行解析,然后传递给Linux内核,因此它被称为命令解释器

将shell从Linux内核分离,避免shell的错误对Linux内核造成影响

第一个shell脚本

1
2
#!/bin/bash
echo 'Hello world'

touch一个bash文件后

1
2
chomod +x hello.sh # shebang
./hello.sh:
1
2
3
4
#!/bin/bahs
echo \
'Hello world' \
'GOOD'

变量

1
变量名=值
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变量

  • HOME:保存当前登录用户的用户主目录的

  • PWD:当前目录

  • SHELL:当前登录用户的登录shell的全路径

  • BASH:保存了bash命令的全路径

  • BASH_VERSION:保持了当前bash命令的版本信息

  • LINENO:保存了当前所执行的脚本文件的行号

  • LANG:国家语言信息

  • PATH:保存了shell启动命令时的目录

  • IFS:Internal Field Separator(内部字段分割符)

位置参数

用于读取命令行参数的变量

1
2
3
4
5
6
#!/bin/bash
echo arg1:$1
echo arg2:$2
echo arg3:$3
echo all:$* # 所有参数
echo all:$@ # 所有参数

特殊参数

变量名 说明
$# 位置参数的个数
$? 上一条命令的
$$ 当前进程的进程ID
$! 最后启动的后台命令的进程ID

使用declare声明变量

1
declare var1
选项 属性
-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} # 默认为0
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
echo  "${fruite[@]}"

获取关联数组中的键的列表

1
echo  "${!fruite[@]}"

展开和引用

路径展开

符号 含义
任意一个字符
* 任意字符串
[ ] [ ]中包含的任意一个字符
[! ]或[^ ] 任意一个不在[ ]的字符
1
2
3
ls main.?
ls *.sh
ls file[1-4].txt

大括号展开

  1. {字符串1,字符串2,字符串3}

    1
    mkdir work/{src,log,tets}
  2. {开始值…结束值}

    1
    2
    echo file-{8..11}.txt
    echo file-{8..11..2}.txt

波浪线展开

用于指定用户主目录的方法

在字符串~ 用户名,则展开为指定用户的主目录。如果省略,则展开为当前登录用户的主目录。

1
ls ~

参数展开

1
2
ls $HOME
ls ${HOME}

使用:-进行展开

:-根据指定的值是是否被赋值来决定要展开的值

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 \\

使用'"进行引用

单引号全部称为字符串

1
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

1
2
3
4
while 命令
do

done
until 命令
do

done

重定向和管道

重定向

输出的重定向

1
ps >result.txt
名称 文件描述符
标准输入 0
标准输出 1
标准错误输出 2

输入的重定向

1
tr b B <word.txt

重定向和追加写入

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
ls | less

命令分组

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 函数名{

}
函数名{

}