shell脚本学习第一课
shell是一种程序设计语言,是访问操作系统内核的服务。
Linux的shell种类常见的有:
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)
Shell脚本执行的两种方法
./shell.sh 根据shell脚本第一行指定的shell执行
/bin/sh test.sh 根据命令行中指定的shell执行
/bin/php test.php
shell变量
定义变量:your_name="runoob.com" for file in `ls /etc`
使用变量:echo $your_name echo ${your_name} echo "I am good at ${skill}Script"
删除变量:unset variable_name
变量类型
1)局部变量
2)环境变量
3)shell变量
shell字符串
单引号:str='this is a string'
双引号:
your_name='qinjx'
str="Hello, I know your are \"$your_name\"! \n"
拼接字符串:
your_name="qinjx"
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
获取字符串长度:
string="abcd"
echo ${#string} #输出 4
提取子字符串:
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
查找子字符串:
string="runoob is a great company"
echo `expr index "$string" is` # 输出 8
Shell数组
bash支持一维数组,不支持多维数组,并且没有限定数组的大小
定义数组::数组名=(值1 值2 ... 值n) array_name=(value0 value1 value2 value3)
或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脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n代表一个数字,1为执行脚本的第一个参数,2为执行脚本的第二个参数,以此类推。
例子:
#!/bin/bash
echo "shell 传递参数实例!";
echo "执行的文件名为:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
执行结果
./test.sh 1 2 3
shell 传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
另外,还有几个特殊字符用来处理参数
| 参数说明 | 说明 |
| $# | 传递到脚本的参数个数 |
| $* |
以一个单字符显示所有向脚本传递的参数。 如"$*"用["]括起来的情况,以"$1 $2 $3"的形式输出所有参数。 |
| $$ | 脚本运行的当前进程ID号 |
| $! | 后台运行的最后一个进程的ID号 |
| $@ |
与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用["]括起来的情况,以"$1""$2""$3"..."$n"的形式输出所有参数 |
| $- | 显示shell使用的当前选项,与set命令功能相同 |
| $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
例子:
#!/bin/bash
echo "Shell传递参数实例!";
echo "第一个参数为:$1";
echo "参数个数为:$#";
echo "传递的参数个数作为一个字符串显示:$*";
执行脚本,结果如下:
./test.sh 1 2 3
Shell传递参数实例!
第一个参数为:1
参数个数为:3
传递的参数个数作为一个字符串显示:1 2 3
$*与$@的区别
相同点:都是引用所有参数
不同点:只有在引号中体现出来。假设脚本运行时写了是哪个参数1、2、3,则"*"等价于"1 2 3"(传递了一个参数),而"@"等价于"1""2""3"(传递了三个参数)。
#!/bin/bash
echo "-- \$* 演示"
for i in "$*";do
echo $i
done
echo "--\$@ 演示"
for i in "$@";do
echo $i
done
执行脚本,结果如下所示
./test.sh 1 2 3
--$* 演示--
1 2 3
--$@ 演示--
1
2
3
Shell数组
Shell数组用括号来表示,元素用“空格”符号分割开。
Shell运算符
expr是一款表达式计算工具,使用它能完成表达式的求值操作。
val=`expr 2 + 2`;
echo "两数之和为:$val";
两点注意:表达式和运算符之间要有空格,例如2+2是不对的,必须写成2 + 2,这与我们熟悉的大多数编程语言不一样。
完整的表达式要被``包含,注意这个字符不是常用的单引号,在Esc键下边。
算数运算符
| 运算符 | 说明 | 举例 |
| + | 加法 | `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 |
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字
| 运算符 | 说明 | 举例 |
| -eq | 检测两个数是否相等,相等返回true | [$a -eq $b]返回false |
| -ne | 检测两个数是否相等,不相等返回true | [$a -nq $b]返回true |
| -gt | 检测左边的数是否大于右边的,如果是,则返回true | [$a -gt $b]返回false |
| -lt | 检测左边的数是否小于右边的,如果是,则返回true | [$a -lt $b]返回true |
| -ge | 检测左边的数是否大于等于右边的,如果是,则返回true | [$a -qe $b]返回false |
| -le | 检测左边的数是否小于等于右边的,如果是,则返回true | [$a -le $b]返回true |
布尔运算符
| 运算符 | 说明 | 举例 |
| ! | 非运算,表达式为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 |
逻辑运算符
| 运算符 | 说明 | 举例 |
| && | 逻辑与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 |
| str | 检测字符串是否为空,不为空返回true | [ $a ]返回true |
文件测试运算符
变量file表示文件"/var/www/runoob/test.sh",它的大小为100字节,具有rw权限。下面的代码,将检测该文件的属性。
| 操作符 | 说明 | 举例 |
| -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 |
Shell echo命令
1、显示普通字符串
echo "It is a test"
这里的双引号完全可以省略,以下命令与上面实例效果一致:
echo It is a test
2、显示转义字符
echo "\"It is a test\""
结果将是
"It is a test"
3、显示变量
#!/bin/bash
read name
echo "$name It is a test"
name接收标准收入的变量,结果将是:
sh test.sh
OK #标准输入
OK It is a test #输出
4、显示换行
echo -e "OK! \n" #-e 开启转义
echo "It is a test"
输出结果
OK!
It is a test
5、显示不换行
#!/bin/bash
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`
结果将显示当前日期
Mon Dec 12 18:33:04 UTC 2016
Shell printf命令
printf跟echo类似,但是可以制定字符串的宽度、左右对齐方式等。
printf format-string [arguments...]
实例:
printf "Hello, Shell\n"
实例:
#!/bin/bash
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n"郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n"杨过 男 48.6543
结果
姓名 性别 体重kg
郭靖 男 66.12
杨过 男 48.65
解释:%-4.2f指格式化为小数,其中.2指保留2位小数
更多实例
#format-string为双引号
printf "%d %s\n" 1 "abc"
#单引号与双引号效果一样
printf '%d %s\n' 1 "abc"
#没有引号也可以输出
printf %s abcdef
#格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string被重要
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
#如果没有arguments,那么%s用NULL代替,%d用0代替
printf "%s and %d \n"
执行结果
1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j
and 0
printf的转义序列
| 序列 | 说明 |
| \a | 警告字符,通常为ASCII的BEL字符 |
| \b | 后退 |
| \c | 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 |
| \f | 换页(formfeed) |
| \n | 换行 |
| \r | 回车(Carriage return) |
| \t | 水平制表符 |
| \v | 垂直制表符 |
| \\ | 一个字面上的反斜杠字符 |
| \ddd | 表示1到3位数八进制值的字符。仅在格式字符串中有效 |
| \0ddd | 表示1到3位的八进制值字符 |
Shell test命令
数值测试
| 参数 | 说明 |
| -eq | 等于则为真 |
| -ne | 不等于则为真 |
| -gt | 大于则为真 |
| -ge | 大于等于则为真 |
| -lt | 小于则为真 |
| -le | 小于等于则为真 |
实例演示
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
输出结果
两个数相等!
字符串测试
| 参数 | 说明 |
| = | 等于则为真 |
| != | 不相等则为真 |
| -z字符串 | 字符串的长度为零则为真 |
| -n字符串 | 字符串的长度不为零则为真 |
实例演示
num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
echo '两个字符串相等!'
eles
echo '两个字符串不相等'
fi
输出结果
两个字符串不相等
文件测试
| 参数 | 说明 |
| -e文件名 | 如果文件存在则为真 |
| -r文件名 | 如果文件存在且可读则为真 |
| -w文件名 | 如果文件存在且可写则为真 |
| -x文件名 | 如果文件存在且可执行则为真 |
| -s文件名 | 如果文件存在且至少有一个字符则为真 |
| -d文件名 | 如果文件存在且为目录则为真 |
| -f文件名 | 如果文件存在且为普通文件则为真 |
| -c文件名 | 如果文件存在且为字符型特殊文件则为真 |
| -b文件名 | 如果文件存在且为块特殊文件则为真 |
实例演示
cd /bin
if test -e ./bash
then
echo '文件已存在'
else
echo '文件不存在'
fi
输出结果
文件已存在!
另外,Shell还提供了与(-a)、或(-o)、非(!)三个逻辑操作符用于将测试条件连接起来,其优先级为:"!"最高,"-a"次之,"-o"最低。例如:
cd /bin
if test -e ./notFile -o -e ./bash
then
echo '有一个文件存在!'
else
echo '两个文件都存在'
fi
输出结果
有一个文件存在
shell脚本学习第一课的更多相关文章
- Shell脚本学习第二课·
Shell文件包含 shell也可以包含外部脚本,语法格式如下: . filename 或 source filename 例如创建两个shell脚本. 脚本1:test1.sh url = &quo ...
- Linux Shell 脚本学习第一天: 使用grep 命令,lsusb, ps -ef, 实现树莓派(Debian OS)时检测到依赖的USB设备启动后,启动终端自动执行shell脚本
1.应用背景: 无人监测的设备,常需要设置应用程序开机启动,程序启动前需要保证调用的设备先启动,运行环境先启动. 2.test.sh部分源码 #!/bin/sh #查看桌面是否启动 while tru ...
- 转 shell脚本学习指南
shell脚本学习指南 以下八点不敢说就能成为你shell脚本学习指南de全部,至少可以让你编写出可靠的shell脚本. 1. 指定bashshell 脚本的第一行,#!之后应该是什么?如果拿这个问题 ...
- Shell脚本学习指南笔记
Shell脚本学习指南 作者:Danbo 2015-8-3 脚本编程语言与编译型语言的差异 许多中型.大型的程序都是用编译型语言写的,例如:C.C+.Java等.这类程序只要从源代码(Source C ...
- Elasticsearch7.X 入门学习第一课笔记----基本概念
原文:Elasticsearch7.X 入门学习第一课笔记----基本概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https: ...
- shell脚本学习之6小时搞定(1)
shell脚本学习之6小时搞定(1) 简介 Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本. Unix/Linux上常见的Shell脚本解释器有bash.sh.csh.ksh等,习惯上把 ...
- Magento学习第一课——目录结构介绍
Magento学习第一课--目录结构介绍 一.Magento为何强大 Magento是在Zend框架基础上建立起来的,这点保证了代码的安全性及稳定性.选择Zend的原因有很多,但是最基本的是因为zen ...
- 笔记——shell脚本学习指南
<shell脚本学习指南>机械工业出版 ISBN 987-7-111-25504-8 第2章 2.4 初级陷阱 1.当今的系统,对#!这一行的长度限制从63到1024个字符都有,尽量不要超 ...
- Shell 脚本学习资料搜集
Shell文档 ChinaUnix上大神“網中人”总结的Shell十三问,强烈推荐,这本书讲得比较精炼,而且都是一些Shell学习中容易把握不住的一些细节难点.每一问都写得非常精彩.ChinaUnix ...
随机推荐
- android socket 线程连接openwrt与arduino单片机串口双向通信
package zcd.netanything; import java.io.BufferedReader; import java.io.InputStreamReader; import jav ...
- u3d中texture2D的Advanced设置解析
经常进行Texture2D的信息设置,以下记录每个属性的意义: 参考手册: file:///D:/Program%20Files%20(x86)/Unity4.7/Editor/Data/Docum ...
- CWMP开源代码研究5——CWMP程序设计思想
声明:本文涉及的开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅号:408797506) 本文介绍自己用过的ACS,其中包括开源版(提供下载包)和商业版(仅提供安装包下载 ...
- 大众点评cat系统的搭建笔记
项目地址:https://github.com/dianping/cat 编译步骤: 这个项目比较另类,把编译需要的jar包,单独放在git分支mvn-repo里了,而且官方文档里给了一个错误的命令提 ...
- ConcurrentHashMap
ConcurrentHashMap是Java5中新增加的一个线程安全的Map集合,可以用来替代HashTable.对于ConcurrentHashMap是如何提高其效率的,可能大多人只是知道它使用了多 ...
- [LeetCode] Design Phone Directory 设计电话目录
Design a Phone Directory which supports the following operations: get: Provide a number which is not ...
- [LeetCode] Kth Largest Element in an Array 数组中第k大的数字
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- 《虚拟伙伴》AR增强现实应用开发总结
一.概述 1.1选题背景 随着时代的发展,人们的生活节奏越来越快,生活质量也越来越高,但却在繁忙之中忽略或者忘记了关心自己成长时代最重要或者最正确的事情和道理.虽然现在有很多社交平台,如微博,微信,f ...
- CoreOS和Docker入门
转载自: http://www.oschina.net/translate/coreos_and_docker_first_steps?cmp CoreOS是一个基于Linux,systemd和Doc ...
- 错误400-The request sent by the client was syntactically incorrect
springMVC中,某个页面提交时报400错误,如下图. 解决方法: 1.在网上找了一下,答案是通常遇到这个错误是因为前端jsp页面的控件名称和controller中接收的参数名称不一致.但 ...