目录
- 执行行脚本
- 注释
- 变量
- 字符串
- 数组
打开文本编辑器,新建一个文件,扩展名为sh
,创建test.sh
文件,并输入代码:
#!/bin/bash
echo "Hello World !"
“#!”
是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell
。echo
命令用于向窗口输出文本。
1、执行脚本
方式一: 保存代码,并cd到目录:
chmod +x ./test.sh #使脚本具有执行权限
./test.sh #执行脚本
注意,一定要写成./test.sh,而不是test.sh。运行其它二进制的程序也一样,直接写test.sh,linux系统会去PATH里寻找有没有叫test.sh的,而只有/bin, /sbin, /usr/bin,/usr/sbin等在PATH里,你的当前目录通常不在PATH里,所以写成test.sh是会找不到命令的,要用./test.sh告诉系统说,就在当前目录找。
方式二: cd到目录
/bin/sh test.sh
2、注释
以“#”
开头的行就是注释,会被解释器忽略,sh
里没有多行注释,只能每一行加一个#
号。只能像这样:
#!bin/bash
# ----------------------------------------------------------------------
# name: test.sh
# version: 1.0
# createTime: 2017-03-14
# description: shell基础
# author: birdben
# email: XXXXXXX@163.com
# ----------------------------------------------------------------------
如果非要要用多行注释可以以下两种方式:
1、可以把这一段要注释的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释一样的效果
2、如下:
echo "我不是单行注释"
# echo "我是单行注释,你看不到我"
echo "我不是多行注释"
:<<COMMENT
echo "我是多行注释1,你看不到我"
echo "我是多行注释2,你看不到我"
COMMENT
echo "我没有看到多行注释1和多行注释2"
执行脚本输出:
我不是单行注释
我不是多行注释
我没有看到多行注释1和多行注释2
可以看到在:<<COMMENT
和COMMENT
之间的脚本代码没有执行,其实COMMENT
可以随意命名,只要别跟中间的注释内容相同即可。当Shell
脚本执行遇到:<<COMMENT
,就不执行脚本了,一直到再碰到COMMENT
后才重新开始执行脚本。如果忘记写COMMENT
或者写错(由于已经不执行脚本了,所以即使写错也不会报错),则:<<COMMENT
之后的脚步将都不会执行。
3、变量
定义变量:
定义变量时,变量名不加美元符号($),如:
variableName="value"
注意,变量名和等号之间不能有空格
变量举例:
a=100
b="hello world"
echo $a
echo $b
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
str="String"
echo "Hi,$strs"
不会输出Strings
,而是输出Hi,
,这是因为Shell
把strs
当成一个变量,而strs
未被赋值,其值为空。正确的方法是:
echo “Hi, ${str}s”
变量重新赋值:
已定义的变量,可以被重新定义,如:
str="String"
echo ${str}
str="hello"
echo ${str}
只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变
示例:
str="String"
echo ${str}
readonly str
str="hello"
echo ${str}
输出:
String
test.sh: line 5: str: readonly variable
删除变量
使用 unset 命令可以删除变量
示例:
str="String"
unset str
echo ${str}
上面脚本将不会有任何输出
shell中特殊变量
变量名只能包含数字、字母和下划线,因为某些包含其他字符的变量有特殊含义,这样的变量被称为特殊变量。
示例:
echo "执行的文件名:$0"
echo "第一个参数为:$1"
echo "第二个参数为:$2"
echo "第三个参数为:$3"
echo "参数个数:$#"
echo "所有参数:$*"
echo "所有参数:$@"
echo "当前Shell进程的ID:$$"
执行脚本:
chmod +x test.sh
./test.sh java oc c++
输出:
执行的文件名:./test.sh
第一个参数为:java
第二个参数为:oc
第三个参数为:c++
参数个数:3
所有参数:java oc c++
所有参数:java oc c++
当前Shell进程的ID:24348
$*
和 $@
的区别
$*
和$@
都表示传递给函数或脚本的所有参数,不被双引号(" ")
包含时,都以"$1" "$2" … "$n"
的形式输出所有参数。
但是当它们被双引号(" ")
包含时,"$*"
会将所有的参数作为一个整体,以"$1 $2 … $n"
的形式输出所有参数;"$@"
会将各个参数分开,以"$1" "$2" … "$n"
的形式输出所有参数。
下面的例子可以清楚的看到 $* 和 $@ 的区别:
echo "print each param from \$*"
for var in $*
do
echo "$var"
done
echo "print each param from \$@"
for var in $@
do
echo "$var"
done
echo "print each param from \"\$*\""
for var in "$*"
do
echo "$var"
done
echo "print each param from \"\$@\""
for var in "$@"
do
echo "$var"
done
执行:
./test.sh a b c
输出:
print each param from $*
a
b
c
print each param from $@
a
b
c
print each param from "$*"
a b c
print each param from "$@"
a
b
c
4、字符串
字符串可以用单引号,也可以用双引号,也可以不用引号
单引号字符串的限制:
1、单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
2、单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
双引号的优点:
1、双引号里可以有变量
2、双引号里可以出现转义字符
示例:
#!/bin/sh
str="hello world"
echo '$str'
echo "$str"
输出:
$str
czc, hello world
字符串拼接
示例:
#!/bin/sh
str="hello world"
str2="${str}!"
str3=""$str"!"
echo $str2
echo $str3
输出:
hello world!
hello world!
获取字符串长度
示例:
#!/bin/sh
str="hello world"
echo ${#str}
输出结果11
提取子字符串
#!/bin/sh
str="hello world"
subStr=${str:1:4}
echo $subStr
输出结果
ello
判断是否包含子串
方式一.
#!/bin/sh
strA="hello world"
strB="hello"
result=$(echo $strA | grep "${strB}")
if [[ "$result" != "" ]]
then
echo "包含"
else
echo "不包含"
fi
输出:包含
先打印长字符串,然后在长字符串中 grep 查找要搜索的字符串,用变量result记录结果
如果结果不为空,说明strA包含strB。如果结果为空,说明不包含。
这个方法充分利用了grep 的特性,最为简洁。
方式二:
#!/bin/sh
strA="hello world"
strB="low"
if [[ $strA =~ $strB ]]
then
echo "包含"
else
echo "不包含"
fi
输出:不包含
利用字符串运算符 =~ 直接判断strA是否包含strB
方式三:利用通配符
A="helloworld"
B="low"
if [[ $A == *$B* ]]
then
echo "包含"
else
echo "不包含"
fi
输出:包含
*代表任意字符,可有可无
5、数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小
在Shell中,用括号来表示数组,数组元素用“空格”符号分割开。定义数组的一般形式为:
array_name=(value1 ... valuen)
示例:
array=("a" "b" "c")
array2=(
"a"
"b"
"c"
)
还可以单独定义数组的各个分量:
array[0]="d"
array[1]="e"
array[2]="f"
可以不使用连续的下标,而且下标的范围没有限制
读取数组元素值的一般格式是:
${array_name[index]}
示例:
a=${array[0]}
使用@ 或 * 可以获取数组中的所有元素
示例:
${array[@]}
${array[*]}
返回数组所有下标
${!array[@]}
获取数组长度的方法与获取字符串长度的方法相同
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}