Hello World
#!/bin/bash
# #!告诉系统用哪一种shell执行
echo "Hello World !"
Shell变量
定义变量
变量名和等号之间不能有空格
name="7e2hj"
readonly name #设置name为只读变量
使用变量
echo ${name}
Shell字符串
单引号
str='this is a string'
单引号里的任何字符都会原样输出
单引号字符串中的变量是无效的
双引号
name='7e2hj'
str="Hello, \"$name\"!"
echo $str
输出结果为:
Hello, "7e2hj"!
双引号里可以有变量和转义字符
获取字符串长度
string="abcd"
echo ${#string} #输出 4
截取字符串
string="abcdefg"
#从第2个字符开始截取4 个字符
echo ${string:1:4} # 输出 bcde
注意:第一个字符的索引值为 0
字符串替换
#用string来替换parameter变量中所有匹配的pattern
${parameter//pattern/string}
Shell数组
bash只支持一维数组
定义数组
array_name=(value0 value1 value2)
#单独定义
#可以不使用连续的下标,且下标的范围没有限制
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
读取数组
valuen=${array_name[n]}
#使用 @ 符号可以获取数组中的所有元素
echo ${array_name[@]}
获取数组长度
#获取数组元素的个数
length=${#array_name[@]}
length=${#array_name[*]}
#获取单个元素的长度
lengthn=${#array_name[n]}
Shell注释
# 单行注释
#多行注释
# [!] 也可以用别的符号代替
:<<!
注释内容
注释内容
!
Shell传参
shell用$n(n表示一个数字)来接收外部传参
$0为执行文件名(包含文件路径)
特殊参数
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$? | 显示最后一条命令的退出状态。0表示没有错误,其他值表明有错误。 |
$* | 以一个单字符串显示所有向脚本传递的参数。 |
$@ | 与$*类似,但不是一个字符串,在引号中返回每个参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
注意:$* 与 $@ 区别:
#!/bin/bash
echo "-- \$* 演示 ---"
for i in "$*"; do
echo $i
done
echo "-- \$@ 演示 ---"
for i in "$@"; do
echo $i
done
执行脚本,输出结果如下所示:
$ chmod +x test.sh
$ ./test.sh 1 2 3
-- $* 演示 ---
1 2 3
-- $@ 演示 ---
1
2
3
Shell运算
原生bash不支持简单的数学运算,但可以通过 expr 命令实现
#!/bin/bash
val=`expr 2 + 2`
#val=`expr 2 \* 2`
echo "两数之和为 : $val"
注意:
- 使用的是反引号
[`]
而不是单引号[']
- 表达式和运算符之间要有空格,例如 2+2 必须写成 2 + 2
- 乘号前必须加反斜杠
\
- 使用$((表达式))也可以实现计算,此处表达式中的
*
不需要转义符号\
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
运算符 | 说明 | 举例 |
---|---|---|
== | 检测两个数是否相等,相等返回 true。 | [ $a == $b ] |
!= | 检测两个数是否不相等,不相等返回 true。 | [ $a != $b ] |
-eq | ==,EQUAL | [ $a -eq $b ] |
-ne | !=,NOT EQUAL | [ $a -ne $b ] |
-gt | >,GREATER THAN | [ $a -gt $b ] |
-lt | <,LESS THAN | [ $a -lt $b ] |
-ge | >=,GREATER THAN OR EQUAL | [ $a -ge $b ] |
-le | <=,LESS THAN OR EQUAL | [ $a -le $b ] |
注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]
字符串运算符
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] |
!= | 检测两个字符串是否不相等,不相等返回 true。 | [ $a != $b ] |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n "$a" ] |
$ | 检测字符串是否为空,不为空返回 true。 | [ $a ] |
注意:
- 使用 -n 时 $a 必须加上双引号
- 使用>,<比较字符串时需要使用
[[]]
或者[\>]
逻辑运算符
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] |
注意:使用双[]
即[[]]
而不是单[]
文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。
操作符 | 说明 | 举例 |
---|---|---|
-e file | 检测文件(包括目录)是否存在 | [ -e $file ] |
-s file | 检测文件是否为空(文件大小是否大于0) 不为空返回 true。 |
[ -s $file ] |
-b file | 检测文件是否是块设备文件 | [ -b $file ] |
-c file | 检测文件是否是字符设备文件 | [ -c $file ] |
-d file | 检测文件是否是目录 | [ -d $file ] |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件) | [ -f $file ] |
-g file | 检测文件是否设置了 SGID 位 | [ -g $file ] |
-k file | 检测文件是否设置了粘着位(Sticky Bit) | [ -k $file ] |
-p file | 检测文件是否是有名管道 | [ -p $file ] |
-u file | 检测文件是否设置了 SUID 位 | [ -u $file ] |
-r file | 检测文件是否可读 | [ -r $file ] |
-w file | 检测文件是否可写 | [ -w $file ] |
-x file | 检测文件是否可执行 | [ -x $file ] |
其他检查符:
- -S: 判断某文件是否 socket。
- -L: 检测文件是否存在并且是一个符号链接。
read命令
read使用
read 命令接收参数 需要使用空格分隔
read firstStr secondStr
echo "第一个参数:$firstStr 第二个参数:$secondStr"
执行结果:
$ sh test.sh
1 2 3 4
第一个参数:1 第二个参数:2 3 4
注意:
- 如果输入的词组个数大于需要的参数个数
- 则多出的词组将整体被作为最后一个参数
read参数
参数说明:
- -p 输入提示文字
- -n 输入字符长度限制(达到6位,自动结束)
- -t 输入限时
- -s 隐藏输入内容
read -p "请输入一段文字:" -n 6 -t 5 -s password
echo -e "\npassword is $password"
执行结果:
$ sh test.sh
请输入一段文字:
password is asdfgh
重定向
重定向命令
文件描述符:
- 0 是标准输入(STDIN)
- 1 是标准输出(STDOUT)
- 2 是标准错误输出(STDERR)
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
command n> file | 将文件描述符为 n 的文件重定向到 file。 |
command &> file | 将错误和正确输出都重定向到 file。 |
command > file 2>&1 | 将错误和正确输出都重定向到 file。 |
command << tag | 从标准输入流读取直到遇到tag。 |
注意:
- n> 之间不能有空格
- 放在>后面的&,表示重定向的目标不是一个文件,而是一个文件描述符
- 而&>file是一种特殊的用法,也可以写成>&file,二者的意思完全相同
/dev/null 文件
如果不想在屏幕显示输出结果, 可以重定向到 /dev/null
command > /dev/null
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃
如果尝试从该文件读取内容,那么什么也读不到
将命令的输出重定向到它,会起到"禁止输出"的效果
流程控制语句
if
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
for
for var in item1 item2 ... itemN
do
command1
done
for((assignment;condition:next))
do
command_1
done;
通常情况下 shell 变量调用需要加 $
但是 for 的 (()) 中不需要,下面来看一个例子:
#!/bin/bash
for((i=1;i<=5;i++));do
echo "这是第 $i 次调用";
done;
while
while condition
do
command
done
unit
until condition
do
command
done
case esac
case 值 in
模式1)
command1
;;
模式2)
command1
;;
esac
例:
case $aNum in
1|2) echo '你选择了 1|2'
;;
3) echo '你选择了 3'
;;
*) echo '你没有输入 1 到 3 之间的数字'
;;
esac
函数
定义函数
[ function ] funname [()]
{
action;
[return int;]
}
说明:
- 可以用function fun() 定义,也可以直接fun() 定义
- 参数返回,使用 return 返回,范围(0~255)
- 如果没有return,将返回最后一条命令运行结果
调用函数
#!/bin/bash
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
函数返回值
#!/bin/bash
test(){
echo $((1+1))
return $((2+2))
}
a=`test`
echo "$?:$a"
执行结果:
4 2
注意:
- $? 获取函数返回值
- $a 获取函数执行的所有输出值
- echo 同 $a
Shell 文件包含
被包含的文件 test1.sh 不需要可执行权限。
. filename
或
source filename
注意:点号.
和文件名中间有空格
Comments NOTHING