helloworld
1 2
| #!/bin/bash echo "Hello World !"
|
运行
chmod +x ./test.sh #使脚本具有执行权限 ./test.sh #执行脚本
使用string
1 2 3 4 5 6 7
| #!/bin/bash str='this is a string' echo ${str} echo ${#str} # 获取字符传长度 echo `expr index ${str} io` # 查找字符 i 或 o 的位置(哪个字母先出现就计算哪个)
|
推荐给所有变量加上花括号,这是个好的编程习惯。
推荐使用双引号 ,单引号则没有这些功能(#{})
使用数组
1 2 3 4 5 6
| #!/bin/bash array_name=(a b c d) echo ${array_name[2]} echo ${array_name[@]} # 获取数组中的所有元素 echo ${#array_name[@]} # 获取数组长度
|
注释
1 2 3 4 5
| # 单行注释 :<<EOF 多行注释 多行注释 EOF
|
启动脚本并且传参
1 2 3 4 5 6 7 8 9 10 11 12
| #!/bin/bash echo "执行的文件名:$0" echo "执行的参数1:$1" echo "执行的参数2:$2" echo "执行的参数3:$3" echo "脚本参数个数:$#" echo "脚本所有参数:$*" echo "脚本进程号:$$" echo "脚本所有参数 "$@"" echo "shell当前选项:$-" echo "shell退出状态:$?"
|
“$@”于$*不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 “ * “ 等价于 “1 2 3”(传递了一个参数),而 “@” 等价于 “1” “2” “3”(传递了三个参数)。
关联数组
1 2 3 4 5 6 7 8 9
| #!/bin/bash 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 echo "数组元素个数为: ${#my_array[*]}" # 数组元素个数为: 4
|
基本运算符
bash不支持原生简单数据运算,但是支持使用expr 和awk命令
- 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
- 完整的表达式要被
包含,注意这个字符不是常用的单引号,在 Esc 键下边。1 2 3
| #!/bin/bash sum = `expr 1 + 1` echo ${sum}
|
基本运算 + - * / % = == !=
注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 **[ $a == $b ]**。
a=$b 把变量 b 的值赋给 a。
[ $a == $b ] 返回 false。
关系运算符
-eq -ne -gt (大于) -ge(大于等于) -lt -le
布尔运算符
非! 或-0 与-a
[ $a -lt 100 -a $b -gt 15 ]
逻辑运算符
&& ||
文件测试运算符
-d file |
检测文件是否是目录,如果是,则返回 true。 |
-f file |
检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 |
-r file |
检测文件是否可读,如果是,则返回 true。 |
-w file |
检测文件是否可写,如果是,则返回 true。 |
-x file |
检测文件是否可执行,如果是,则返回 true。 |
-s file |
检测文件是否为空(文件大小是否大于0),不为空返回 true。 |
-e file |
检测文件(包括目录)是否存在,如果是,则返回 true。 |
shell echo命令
1 2 3 4 5 6 7 8 9 10 11 12
| #!/bin/bash echo "helloWorld" # helloWorld echo helloWorld # helloWorld echo \"helloWorld\" #helloWorld read name echo "$name It is a test" echo -e "OK! \c" # -e 开启转义 \c 不换行 echo "It is a test" echo '$name\"' # 原样输出字符串,不进行转义或取变量(用单引号) echo "It is a test" > myfile # 显示结果生成到文件 echo `date` # 显示命令执行结果 命令用反引号`
|
shell printf命令
printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认的 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。
%s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实数,以小数形式输出。
%-10s 指一个宽度为 10 个字符(**-** 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中 .2 指保留2位小数。
1 2 3
| #!/bin/bash printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
|
\c |
抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 |
\f |
换页(formfeed) |
\n |
换行 |
\r |
回车(Carriage return) |
\t |
水平制表符 |
\v |
垂直制表符 |
字符串控制
-z 字符串 |
字符串的长度为零则为真 |
-n 字符串 |
字符串的长度不为零则为真 |
流程控制
if else
1 2 3 4 5 6 7
| if condition then command1 command2 ... commandN fi
|
if elseif else
1 2 3 4 5 6 7 8 9
| if condition1 then command1 elif condition2 then command2 else commandN fi
|
if else 的 […] 判断语句中大于使用 -gt,小于使用 -lt。
如果使用 ((…)) 作为判断语句,大于和小于可以直接使用 > 和 **<**。
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
for循环
1 2 3 4 5 6 7 8 9
| for var in item1 item2 ... itemN do command1 command2 ... commandN done # 写成一行 for var in item1 item2 ... itemN; do command1; command2… done;
|
while循环
1 2 3 4 5 6 7 8 9
| while condition do command done #无限循环 while : do command done
|
untill循环
1 2 3 4
| until condition do command done
|
until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。
一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。
case … esac多选择语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| echo '输入 1 到 4 之间的数字:' echo '你输入的数字为:' read aNum case $aNum in 1) echo '你选择了 1' ;; 2) echo '你选择了 2' ;; 3) echo '你选择了 3' ;; 4) echo '你选择了 4' ;; *) echo '你没有输入 1 到 4 之间的数字' ;; esac
|
跳出循环
1 2
| break # 跳出所有循环 continue # 跳出当前循环
|
shell 函数
所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
传参如同启动脚本并且传参的格式
$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
函数与命令的执行结果可以作为条件语句使用。要注意的是,和 C 语言不同,shell 语言中 0 代表 true,0 以外的值代表 false。
$? 仅对其上一条指令负责,一旦函数返回后其返回值没有立即保存入参数,那么其返回值将不再能通过 $? 获得。
1 2 3 4 5 6 7 8 9
| [ function ] funname [()]
{
action;
[return int;]
}
|
实例(有返回值)
1 2 3 4 5 6 7 8 9 10 11 12
| #!/bin/bash funWithReturn(){ echo "这个函数会对输入的两个数字进行相加运算..." echo "输入第一个数字: " read aNum echo "输入第二个数字: " read anotherNum echo "两个数字分别为 $aNum 和 $anotherNum !" return $(($aNum+$anotherNum)) } funWithReturn echo "输入的两个数字之和为 $? !"
|
输入输出重定向
命令 |
说明 |
command > file |
将输出重定向到 file。 |
command < file |
将输入重定向到 file。 |
command >> file |
将输出以追加的方式重定向到 file。 |
n > file |
将文件描述符为 n 的文件重定向到 file。 |
n >> file |
将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m |
将输出文件 m 和 n 合并。 |
n <& m |
将输入文件 m 和 n 合并。 |
<< tag |
将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
接着以上实例,我们需要统计 users 文件的行数,执行以下命令:
$ wc -l users 2 users
也可以将输入重定向到 users 文件:
$ wc -l < users 2
注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。
Here Document
Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
1 2 3
| command << delimiter document delimiter
|
/dev/null 文件
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
$ command > /dev/null
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
- 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
- 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
- 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
如果希望 stderr 重定向到 file,可以这样写:
$ command 2>file
shell 文件包含
. filename # 注意点号(.)和文件名中间有一空格 或 source filename
用以调用被包含的参数
被包含的文件 test1.sh 不需要可执行权限。