1小时学会Shell基础
初识Shell
1. Shell 是一个用C语言编写的应用程序,是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
shell通指shell脚本,但shell和shell script是两个不同的概念。
本教程关注的是 Bash,不区分 BourneShell 和 Bourne Again Shell,
#!/bin/sh,可改为#!/bin/bash。
2. 第一个shell脚本:
vi/vim命令来创建个文件test.sh,扩展名为sh(sh代表shell),扩展名不影响脚本执行
#!/bin/bash #"#!"约定标记,脚本要什么解释器来执行,使用哪一种Shell。
echo "Hello World!" #echo命令用于向窗口输出文本
运行Shell脚本有两种方法:
1、作为可执行程序:
将上面的代码保存为test.sh,并cd到相应目录:
chmod +x ./test.sh #使脚本具有执行权限
./test.sh #执行脚本
注:直接写test.sh,linux系统会去PATH里寻找有没有叫test.sh的,而只有/bin,/sbin, /usr/bin,/usr/sbin等在PATH里,当前目录通常不在PATH里,所以写成test.sh是会找不到命令的,要用./test.sh告诉系统说,就在当前目录找。
2、作为解释器参数:直接运行解释器,其参数就是shell脚本的文件名,如:
/bin/sh test.sh
/bin/php test.php
注:不需要在第一行指定解释器信息
Shell 变量
3.Shell 变量
变量名不加美元符号
首个字符必须为字母(a-z,A-Z)。
中间不能有空格,可以使用下划线(_)。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。
使用变量
使用定义过的变量,变量名前面加美元符号如:
your_name="qinjx"
echo $your_name
echo ${your_name}
变量名外面的花括号是可选的,加花括号是为了帮助解释器识别变量的边界(规范)
4. Shell 字符串
字符串可以用单引号,也可以用双引号,也可以不用引号
单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
双引号的优点:
双引号里可以有变量
双引号里可以出现转义字符
拼接字符串:echo$greeting $greeting_1
获取字符串长度:echo${#string}
提取子字符串:echo ${string:1:4}
查找子字符串:echo `expr index "$string"is` 以上脚本中 "`" 是反引号
5. Shell 数组
定义数组的一般形式为:数组名=(值1值2 ... 值n)
读取数组的一般格式是:${数组名[下标]}用@符号可以获取数组中的所有元素
echo ${array_name[@]}
获取数组长度与获取字符串长度的方法相同,如:
# 取得数组元素的个数:length=${#array_name[@]} 或length=${#array_name[*]}
# 取得数组单个元素的长度lengthn=${#array_name[n]}
6.Shell 注释
以"#"开头的行是注释, sh里没有多行注释(花括号括起来),只能每行加一个#号。
Shell 传递参数
7.脚本内获取参数的格式为:$n。
$# 传递到脚本的参数个数。
$* 与 $@ 区别:
相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)
Shell 基本运算符
8. 原生bash不支持数学运算,但可以通过其他命令来实现,如 awk 和 expr,expr
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
如:两个数相加
#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val"
注意:使用的是反引号 ` 而不是单引号 '
表达式和运算符之间要有空格
乘号(*)前边必须加反斜杠(\)才能实现乘法运算;
9.关系运算符if test$[num1] -eq $[num2]
-eq ==
-ne !=
-gt >
-lt >
-ge >=
-le <=
10. 布尔运算符if test -e./notFile -o -e ./bash
! 非
-o 或
-a 与
11. 字符串运算符 if test num1=num2
= 等于则为真
!= 不相等则为真
-z 检测字符串长度是否为0,为0返回 true。
-n 检测字符串长度是否为0,不为0返回 true。
str 检测字符串是否为空, 不为空返回 true。
12. 文件测试运算符if test -e ./bash
-b file 检测文件是否是块设备文件,
-c file 检测文件是否是字符设备文件
-d file 检测文件是否是目录
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件)
-g file 检测文件是否设置了 SGID 位
-k file 检测文件是否设置了粘着位(StickyBit)
-p file 检测文件是否是具名管道
-u file 检测文件是否设置了 SUID 位f
-r file 检测文件是否可读
-w file 检测文件是否可写
-x file 检测文件是否可执行
-s file 检测文件是否为空(文件大小是否大于0)
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。
Shell 输出
13. 用于字符串的输出。命令格式:echo string
read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
echo -e"OK!\n" # -e 开启转义 换行
echo -e"OK! \c" # -e 开启转义 \c 不换行
显示结果定向至文件echo"It is a test" > myfile
原样输出字符串,不进行转义或取变量(用单引号) echo'$name\"'
显示命令执行结果echo `date`
14. printf的脚本比使用echo移植性好。
语法:printf format-string [arguments...]
format-string: 为格式控制字符串
arguments: 为参数列表。
默认printf不会像 echo 自动添加换行符,我们可以手动添加 \n。
%s %c %d %f都是格式替代符
#!/bin/bash
printf "%-10s %-8s%-4s\n" 姓名性别体重kg
printf "%-10s %-8s%-4.2f\n" 郭靖男 66.1234
printf "%-10s %-8s%-4.2f\n" 杨过男 48.6543
printf "%-10s %-8s%-4.2f\n" 郭芙女 47.9876
执行脚本,输出结果如下所示:
姓名 性别 体重kg
郭靖 男 66.12
杨过 男 48.65
郭芙 女 47.99
#-表示左对齐,没有则表示右对齐,.2指保留2位小数
\a 警告字符,通常为ASCII的BEL字符
\b 后退
\c 抑制(不显示)输出结果中任何结尾的换行字符
Shell test命令
检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
Shell 流程控制
(1)if语句语法格式:
if condition
then
command1
command2 elif
...
commandN else else
fi (倒过来写)
(2)for循环一般格式为:
forvar in item1 item2 ... itemN
do
command1
command2
...
commandN
done
(3)while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:
while condition
do
command
done
while循环可用于读取键盘信息。
echo '按下 <CTRL-D>退出'
echo -n '输入你最喜欢的电影名: '
while read FILM
do
echo "是的!$FILM是一部好电影"
done
(4)无限循环语法格式:
while :
do
command
done
while true
do
command
done
for (( ; ; ))
(5)until语法格式:
until condition
do
command
done
(6)case语句
case 值 in
模式1)
command1
;;
模式2)
command1
;;
esac
break命令允许跳出所有循环(终止执行后面的所有循环)
continue它不会跳出所有循环,仅仅跳出当前循环。
(7)esac
case的语法和C family语言差别很大,它需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break。
Shell 函数
shell中函数的定义格式如下:
[ function ] funname [()]
{
action;
[return int;]
}
例子:
#!/bin/bash
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
Shell 输入/输出重定向
重定向命令列表如下:
命令 说明
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 之间的内容作为输入。
command1 > file1
上面这个命令执行command1然后将输出的内容存入file1。
任何file1已存在内容将被新内容替代。如要将新内容添加在文件末尾,使用>>操作符。
$ echo "W3Cschool教程:www.w3cschool.cn"> users
$ cat users
W3Cschool教程:www.w3cschool.cn
$
Here Document是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
它的基本的形式如下:
command << delimiter
document
delimiter
在命令行中通过 wc -l 命令计算 HereDocument 的行数:
将 Here Document用在脚本中,例如:
#!/bin/bash
# author:W3Cschool教程
# url:www.w3cschool.cn
cat << EOF
欢迎来到
W3Cschool教程
www.w3cschool.cn
EOF
执行以上脚本,输出结果:
欢迎来到
W3Cschool教程
执行某个命令,但不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
Shell 文件包含
Shell 文件包含的语法格式如下:
. filename # 注意点号(.)和文件名中间有一空格
或
source filename
创建两个 shell 脚本文件。
test1.sh 代码如下:
#!/bin/bash
url="http://www.w3cschool.cn"
test2.sh 代码如下:
#!/bin/bash
#使用 .号来引用test1.sh文件
. ./test1.sh
# 或者使用以下包含文件代码
# source ./test1.sh
echo "W3Cschool教程官网地址:$url"
接下来,我们为 test2.sh 添加可执行权限并执行:
$ chmod +x test2.sh
$ ./test2.sh
W3Cschool教程官网地址:http://www.w3cschool.cn
注:被包含的文件 test1.sh 不需要可执行权限。