概述:
shell是我们通过命令行与操作系统沟通的语言
shell脚本可以直接在命令行中执行,也可以将一套逻辑组织成一个文件,方便使用
Linux系统中一般默认使用bash
文件开头需要写 #! /bin/bash 指明bash为脚本解释器
脚本实例---新建一个test.sh文件
#!/bin/bash
echo “hello world!"
运行方式:
作为可执行文件:
~$ chmod +x test.sh #使脚本具有可执行权限(可以用ls -l查看文件所拥有的权限)
~$./test.sh #当前路径下执行
~$/home/acs/test.sh #绝对路径下执行
~$ ~/test.sh #家目录路径下执行
用解释器执行:
~$ bash test.sh
注释:
单行注释:每行中 # 之后的内容均是注释
多行注释: :<<(任意字符串) ------- ( : 可加可不加)
、、、、、
、、、、、
(与开头保持一致即可)
变量
定义变量:
不需要加 $ 符号----> name1='abc' == name2="abc" == name3=yxc
定义变量时,等号两边不能有空格
定义变量的时候变量都是字符串,但当变量需要是整数时,会自动转换
使用变量:需要加上 $ 符号,或者 ${} 。花括号是可选的,主要为了帮助解释器识别变量边界
name=abc
echo $name #输出abc
echo ${name} #输出abc
echo ${name}acwing #输出abcacwing
只读变量:使用 readonly 或者 declare 可以将变量变为只读
name=yxc
readonly name
declare -r name #两种写法均可
name=abc #会报错,此时name为只读
删除变量 : unset 可以删除变量
name=yxc
unset name
echo $name #输出空行
变量类型:
1.自定义变量(局部变量):子进程不能访问的变量
2.环境变量(全局变量):子进程可以访问的变量
<<eof
自定义变量改成环境变量
在命令行模式下
eof
name=yxc
export name #第一种方法
declare -x name #第二种方法 自定义--->环境是 -x
#环境变量改为自定义变量
export name=yxc #定义环境变量
declare +x name #改为自定义变量 环境到自定义是 +x
字符串:
字符串可以用单引号,也可以用双引号,也可以不用引号
单/双引号的区别:
单引号中的内容会原样输出,不会执行、不会取变量
双引号的内容可以执行、可以取变量
name=yxc #不用引号
echo 'hello,$name \"hh\" ' #单引号字符串,输出 hello,$name \"hh\"
echo "hello,$name \"hh\" " #双引号字符串,输出 hello,yxc,"hh"
获取字符串长度
name="yxc"
echo ${#name} #输出3
提取子串
name="hello,yxc"
echo ${name:0:5} #提取从0开始的5个字符[0,5]
其他的事项:
type + 命令可以解释该命令来源(内嵌命令,第三方命令等)
被声明为只读的变量无法被unset删除
bash可以用来开一个新的进程,exit 或 ctrl + d 可以退出新的bash
字符串中,不加引号和双引号效果相同
如果一个变量不存在的话,他的值是空
在一个bash中自定义的bash变量仅可以被当前bash访问,通过bash命令开启的子进程也无法访问,export后变量变为环境变量,就可以被全局访问
验证一个变量是全局还是局部:
在当前bash里声名一个name=yxc
然后再新开一个bash(原来的bash会睡眠掉)
使用echo $name 如可以输出则是全局变量,反之是局部变量
默认变量
文件参数变量:
在执行shell脚本时,可以向脚本传递参数。$1 是第一个参数, $2 是第二个参数,以此类推。特殊的:$0是文件名(包含路径)
#创建文件 test。sh
#! /bin/bash
echo "文件名:"$0
echo "第一个参数:"$1
echo "第二个参数:"$2
echo "第三个参数:"$3
执行该脚本:
chmod +x test.sh
./test.sh 1 2 3
文件名:./test.sh
第一个参数:1
第二个参数:2
第三个参数:3
其他参数相关变量
$$ 脚本当前运行的进程ID
$? 上一条命令的退出状态(不是stdout,而是exit code) 0表示正常退出,其他值表示错误
$(command) 返回command这条命令的stdout(可嵌套)
`command` 返回command这条命令的stdout(不可嵌套)
其他:
向脚本传递参数时,参数个数超过1位需要用大括号括起来 echo ${10}
$0是文件名(包含路径),其实就是输入的第一段,输入绝对路径就显示绝对路径,输入相对路径就显示相对路径
分清 exit code 和 stdout
./test.sh 1 2 3 4 最开始的. 代表当前路径,在当前路径下执行的意思
数组
数组中可以存放多个不同类型的值,只支持一维数组,初始化时不需要指明数组大小,数组下标从0开始。
定义:
数组用小括号表示,元素之间用空格隔开。例如:
array=(1 abc "def" yxc)
也可以直接定义数组中某个元素的值:
array[0]=1
array[1]=abc
array[2]="def"
array[3]=yxc
读取数组中某个元素的值:
格式: ${array[index] }
array=(1 abc "abc" yxc)
echo ${array[0]}
echo ${array[1]}
读取整个数组:
格式:${arrau[@]} ${array[*] }
array=(1 abc "def" yxc)
echo ${array[@]} #第一种写法
echo ${array[*]} #第二种写法
数组长度:
类似于字符串:${#array[@ / * ]}
其他:
在读取整个数组时,未定义的部分不会显示。比如定义了array[0]/[1]/[2]/[3][1000],利用echo ${array[@]} 输出时,只会显示定义的数组那 4个值
对上例求长度时,结果是4,而不会是1000