---------------------新建shell脚本-------------------
新建一个文件 test.sh,扩展名为 sh。
输入一些代码,第一行一般是这样:
像 #!/bin/sh,它同样也可以改为 #!/bin/bash。
#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。
实例
#!/bin/bash
echo "Hello World !"
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
echo 命令用于向窗口输出文本。
------------变量-------------
变量定义 name="zhangsan"
变量使用 echo $name echo ${name}
变量只读 name="zhangsan" readonly name
删除 unset name (不能删除只读变量)
字符串 可用单引号 或 双引号
str='this is a string'
单引号:任何字符都会原样输出(变量是无效的),单引号必须成对出现(不可出现转义字符);
双引号:里面可有变量,可以出现转义字符;
字符串长度
string="abcd"
echo ${#string} 输出4
提取字符串
echo ${string:1:2} 输出ab
查找字符串
查找c或d的位置(哪个字母先出现就先计算哪个 使用反引号)
echo `expr index "$string" cd` 输出3
-------------数组--------------
定义:array=(value0 value1 value2 value3)
读取 ${array[0]} value0
获取数组中所有元素 ${array[@]}
获取数字元素个数 ${#array[@]} ${#array[*]}
获取数组单个元素长度 ${#array[n]}
--------------注释--------------
单行注释 #
多行注释
:<<EOF
内容
EOF
:<<!
内容
!
---------------参数传递------------------
$n n代表一个数字,1为执行脚本的第一个参数,2为执行脚本的第二个参数。。。。。。
以下实例我们向脚本传递三个参数,并分别输出,其中 $0 为执行的文件名:
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
为脚本设置可执行权限,并执行脚本,输出结果如下所示:
$ 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表示没有错误,其他任何值表明有错误。
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
echo "Shell 传递参数实例!";
echo "第一个参数为:$1";
echo "参数个数为:$#";
echo "传递的参数作为一个字符串显示:$*";
执行脚本,输出结果如下所示:
$ chmod +x test.sh
$ ./test.sh 1 2 3
Shell 传递参数实例!
第一个参数为:1
参数个数为:3
传递的参数作为一个字符串显示:1 2 3
$* 与 $@ 区别:
相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
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
-----------------数组--------------
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小。
与大部分编程语言类似,数组元素的下标由0开始。
定义:my_array=(A B "C" D)
读取单个:${my_array[0]} A
读取所有:${my_array[*]} ${my_array[@]}
获取长度:${#my_array[*]} ${#my_array[@]}
------------------基本运算符--------------
种类(算数运算符 关系运算符 布尔运算符 字符串运算符 文件测试运算符)
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
例如,两个数相加(注意使用的是反引号 ` 而不是单引号 '):
!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val" 4
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。
-----------------算术运算符------------------
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例
+ 加法 `expr $a + $b` 结果为 30。
- 减法 `expr $a - $b` 结果为 -10。
* 乘法 `expr $a * $b` 结果为 200。 乘号(*)前边必须加反斜杠()才能实现乘法运算;
/ 除法 `expr $b / $a` 结果为 2。
% 取余 `expr $b % $a` 结果为 0。
= 赋值 a=$b 将把变量 b 的值赋给 a。
== 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。
!= 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。
注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。
------------------------关系运算符---------------------
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。
------------------------布尔运算符-----------------------
下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。
------------------------逻辑运算符-----------------------
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例
&& 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true
------------------------字符串运算符---------------------
下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":
运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否为0,不为0返回 true。 [ -n "$a" ] 返回 true。
$ 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。
-------------------------文件测试运算符-------------------
文件测试运算符用于检测 Unix 文件的各种属性。
属性检测描述如下:
操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。
其他检查符:
-S: 判断某文件是否 socket。
-L: 检测文件是否存在并且是一个符号链接。
-------------------------shell echo命令----------------------
1.显示普通字符串:
echo "It is a test"
这里的双引号完全可以省略,以下命令与上面实例效果一致:
echo It is a test
2.显示转义字符
echo ""It is a test""
结果将是:
"It is a test"
同样,双引号也可以省略
3.显示变量
read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
#!/bin/sh
read name
echo "$name It is a test"
以上代码保存为 test.sh,name 接收标准输入的变量,结果将是:
[root@www ~]# sh test.sh
OK #标准输入
OK It is a test #输出
4.显示换行
echo -e "OK!
" # -e 开启转义
echo "It is a test"
输出结果:
OK!
It is a test
5.显示不换行
#!/bin/sh
echo -e "OK! c" # -e 开启转义 c 不换行
echo "It is a test"
输出结果:
OK! It is a test
6.显示结果定向至文件
echo "It is a test" > myfile
7.原样输出字符串,不进行转义或取变量(用单引号)
echo '$name"'
输出结果:
$name"
8.显示命令执行结果
echo `date`
注意: 这里使用的是反引号 `, 而不是单引号 '。
结果将显示当前日期
Thu Jul 24 10:08:46 CST 2014
---------------------Shell printf 命令-----------------------
printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。
默认 printf 不会像 echo 自动添加换行符,我们可以手动添加
。
printf 命令的语法:
printf format-string [arguments...]
参数说明:
format-string: 为格式控制字符串
arguments: 为参数列表。
实例如下:
$ echo "Hello, Shell"
Hello, Shell
$ printf "Hello, Shell
"
Hello, Shell
$
接下来,我来用一个脚本来体现printf的强大功能:
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
printf "%-10s %-8s %-4s
" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f
" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f
" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f
" 郭芙 女 47.9876
执行脚本,输出结果如下所示:
姓名 性别 体重kg
郭靖 男 66.12
杨过 男 48.65
郭芙 女 47.99
%s %c %d %f都是格式替代符
%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中.2指保留2位小数。
更多实例:
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
# format-string为双引号
printf "%d %s
" 1 "abc"
# 单引号与双引号效果一样
printf '%d %s
' 1 "abc"
# 没有引号也可以输出
printf %s abcdef
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def
printf "%s " abc def
printf "%s %s %s " a b c d e f g h i j
# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d
"
执行脚本,输出结果如下所示:
1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j
and 0
printf的转义序列
序列 说明
a 警告字符,通常为ASCII的BEL字符
后退
c 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
f 换页(formfeed)
换行
回车(Carriage return)
水平制表符
v 垂直制表符
\ 一个字面上的反斜杠字符
ddd 表示1到3位数八进制值的字符。仅在格式字符串中有效