一,创建与执行
1、创建一个sh文件: vim a.sh
插入语句:#!/bin/bash
echo "hello"
2、执行有3种方式:source, sh , 绝对/相对路径执行(./)
(1)直接执行文件(未添加执行权限):sh a.sh (a.sh 目前是文件)
(2)直接执行文件(未添加执行权限):source a.sh
共同点:sh和source都可以执行文件或脚本
sh和source 区别: sh 是直接创建一个新的进程去执行脚本,source 是在本sh进程中
直接执 行脚本(不会创建进程)
添加执行权限:chmod +x a.sh (a.sh 目前是脚本)
(3)执行当前路径下的sh(添加执行权限) : ./a.sh (只能执行脚本)
执行绝对路径的sh(添加执行权限): /root/a.sh (只能执行脚本)
绝对/相对路径执行过程:也是直接创建一个新的进程去执行脚本
3、变量添加export 修饰
export aa="name" :添加export修饰,则代表可以被子进程访问
二、变量
2.1 局部变量
定义变量时,变量名不加美元符号,使用需要加 $
注意,变量名和等号之间不能有空格。同时,变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线 _。
- 不能使用标点符号。
- 不能使用bash里的关键字(可用help命令查看保留关键字)。
#局部变量
name="zhangsan" #直接赋值
for file in `ls /etc` #用语句给变量赋值 `是反引号
for file in $(ls /etc) #用语句给变量赋值
#变量调用
echo $name
echo $(name)
#只读变量
readonly name //此时 name 为只读变量
#删除变量
unset name //此时局部不存在name
2.2 shell的字符串
字符串可以用单引号,也可以用双引号,也可以不用引号。
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
- 双引号里可以有变量
- 双引号里可以出现转义字符
#定义字符串
name1=zhangsan //可以不加引号
name2='li si' //必须家引号,因为中间有空格
#拼接字符串
name3="hello, $name1"
name4="hello, ${name1}"
echo $name3 $name4 #结果:hello, zhangsan hello, zhangsan
name3='hello, '$name1''
name4='hello, $name1'
name5='hello, ${name1}'
echo $name3 $name4 $name5 #结果:hello, zhangsan hello, $name1 hello, ${name1}
#字符长度
echo ${#name1} # 输出 8
echo ${#name1[0]} # 输出 8 // 变量为数组时,${#string} 等价于 ${#string[0]}
echo ${name1:2:5} # 输出 angsa
#查找字符
echo `expr index "$name1" ag` # 输出 3 //查找字符a或g的位置(哪个先出现就计算哪个)
2.3 数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。数组元素的下标由 0 开始编号。
在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
数组名=(值1 值2 ... 值n)
name=("123" "456" "789" "012")
echo ${name[1]} #结果:456
#获取数组中的所有元素:使用 @ 或 *
echo "${name[*]}" #结果:123 456 789 012
echo "${name[@]}" #结果:123 456 789 012
#获取数组的长度:使用 #
echo "${#name[*]}" #结果:4
echo "${#name[@]}" #结果:4
echo "${#name[1]}" #结果:3
关联数组
Bash 支持关联数组,可以使用任意的字符串、或整数作为下标来访问数组元素,关键字: declare
格式:declare -A 数组名 # -A 选项就是用于声明一个关联数组
#关联数组 两种方式
#1 直接定义创建
declare -A site=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")
echo ${site["runoob"]} #结果:www.runoob.com
#2 先定义 后创建
declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"
echo ${site["runoob"]} #结果:www.runoob.com
#获取数组的所有键:使用 !
echo "${!site[*]}" #结果:google runoob taobao
2.4 注释
单行注释:#
多行注释::<<EOF
xxxxxxxxxxx
EOF
2.5传递参数
向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
$ chmod +x test.sh $ ./test.sh 1 2 3 Shell 传递参数实例! 执行的文件名:./test.sh 第一个参数为:1 第二个参数为:2 第三个参数为:3
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
$* 与 $@ 区别:
- 相同点:都是引用所有参数。
- 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)