登录  | 加入社区

黑狼游客您好!登录后享受更多精彩

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

查看: 605|回复: 0

shell脚本极简教程

[复制链接]

216

主题

1

帖子

0

现金

黑狼菜鸟

Rank: 1

积分
0
发表于 2017-12-4 02:24:38 | 显示全部楼层 |阅读模式 来自 澳大利亚
一,shell题记不懂shell的步伐员不是好步伐员,学习shell是为了主动化,利用主动化可以非常有用的进步工作服从。没有一个大公司不要求linux的根本技能的,只是差别岗位要求把握的水平差别。


二,shell简介

Shell自己是一个用C语言编写的步伐,它是用户利用Unix/Linux的桥梁,用户的大部门工作都是通过Shell完成的。Shell既是一种下令语言,又是一种步伐计划语言。作为下令语言,它交互式地表明和实行用户输入的下令;作为步伐计划语言,它界说了各种变量和参数,并提供了很多在高级语言中才具有的控制布局,包罗循环和分支。
它固然不是Unix/Linux体系内核的一部门,但它调用了体系焦点的大部门功能来实行步伐、创建文件并以并行的方式和谐各个步伐的运行。因此,对于用户来说,shell是最紧张的实用步伐,深入相识和纯熟把握shell的特性极其利用方法,是用好Unix/Linux体系的关键。
可以说,shell利用的纯熟水平反映了用户对Unix/Linux利用的纯熟水平。
Shell有两种实行下令的方式:
交互式(Interactive):表明实行用户的下令,用户输入一条下令,Shell就表明实行一条。
批处置惩罚(Batch):用户事先写一个Shell脚本(Script),此中有许多条下令,让Shell一次把这些下令实行完,而不必一条一条地敲下令。
Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是表明实行的,不必要编译,Shell步伐从脚本中一行一行读取并实行这些下令,相称于一个用户把脚本中的下令一行一行敲到Shell提示符下实行。


Shell初学者请留意,在寻常应用中,发起不要用 root 帐号运行 Shell 。作为平凡用户,不管您故意照旧偶然,都无法粉碎体系;但假如是 root,那就差别了,只要敲几个字母,就大概导致劫难性结果。


三,几种常见的shell

上面提到过,Shell是一种脚本语言,那么,就必须有表明器来实行这些脚本。
Unix/Linux上常见的Shell脚本表明器有bash、sh、csh、ksh等,风俗上把它们称作一种Shell。我们常说有多少种Shell,实在说的是Shell脚本表明器。
bash:bash是Linux尺度默认的shell,本教程也基于bash解说。bash由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的缩写,内部下令一共有40个。
Linux利用它作为默认的shell是由于它有诸如以下的特色:

  • 可以利用雷同DOS下面的doskey的功能,用方向键查阅和快速输入并修改下令。
  • 主动通过查找匹配的方式给出以某字符串开头的下令。
  • 包罗了自身的资助功能,你只要在提示符下面键入help就可以得到相干的资助。
sh:sh 由Steve Bourne开辟,是Bourne Shell的缩写,sh 是Unix 尺度默认的shell。
ash:ash shell 是由Kenneth Almquist编写的,Linux中占用体系资源最少的一个小shell,它只包罗24个内部下令,因而利用起来很不方便。
csh:csh 是Linux比力大的内核,它由以William Joy为代表的共计47位作者编成,共有52个内部下令。该shell实在是指向/bin/tcsh如许的一个shell,也就是说,csh实在就是tcsh。
ksh:ksh 是Korn shell的缩写,由Eric Gisin编写,共有42条内部下令。该shell最大的长处是险些和贸易发行版的ksh完全兼容,如许就可以在不消费钱购买贸易版本的环境下实验贸易版本的性能了。
留意:bash是 Bourne Again Shell 的缩写,是linux尺度的默认shell ,它基于Bourne shell,吸取了C shell和Korn shell的一些特性。bash完全兼容sh,也就是说,用sh写的脚本可以不加修改的在bash中实行。


四,编程型息争释型语言的区别

大要上,可以将步伐计划语言可以分为两类:编译型语言息争释型语言。
编译型语言

  许多传统的步伐计划语言,比方Fortran、Ada、Pascal、C、C++和Java,都是编译型语言。这类语言必要预先将我们写好的源代码(source code)转换成目的代码(object code),这个过程被称作“编译”。
  运行步伐时,直接读取目的代码(object code)。由于编译后的目的代码(object code)非常靠近盘算机底层,因此实行服从很高,这是编译型语言的长处。
  但是,由于编译型语言多半运作于底层,所处置惩罚的是字节、整数、浮点数或是其他呆板层级的对象,每每实现一个简朴的功能必要大量复杂的代码。比方,在C++里,就很难举行“将一个目次里全部的文件复制到另一个目次中”之类的简朴操纵。
表明型语言

  表明型语言也被称作“脚本语言”。实行这类步伐时,表明器(interpreter)必要读取我们编写的源代码(source code),并将其转换成目的代码(object code),再由盘算机运行。由于每次实行步伐都多了编译的过程,因此服从有所降落。
  利用脚本编程语言的利益是,它们多半运行在比编译型语言还高的层级,可以或许容易处置惩罚文件与目次之类的对象;缺点是它们的服从通常不如编译型语言。不外衡量之下,通常利用脚本编程照旧值得的:花一个小时写成的简朴脚本,同样的功能用C或C++来编写实现,大概必要两天,而且一样平常来说,脚本实行的速率已经够快了,快到足以让人忽略它性能上的题目。脚本编程语言的例子有awk、Perl、Python、Ruby与Shell。


五,什么时间利用shell?

由于Shell好像是各UNIX体系之间通用的功能,而且颠末了POSIX的尺度化。因此,Shell脚本只要“专心写”一次,即可应用到许多体系上。因此,之以是要利用Shell脚本是基于:

  • 简朴性:Shell是一个高级语言;通过它,你可以简便地表达复杂的操纵。
  • 可移植性:利用POSIX所界说的功能,可以做到脚本无须修改就可在差别的体系上实行。
  • 开辟轻易:可以在短时间内完成一个功能强盛又妤用的脚本。
  但是,思量到Shell脚本的下令限定和服从题目,下列环境一样平常不利用Shell:

  • 资源麋集型的使命,尤其在必要思量服从时(好比,排序,hash等等)。
  • 必要处置惩罚大使命的数学操纵,尤其是浮点运算,准确运算,大概复杂的算术运算(这种环境一样平常利用C++或FORTRAN 来处置惩罚)。
  • 有跨平台(操纵体系)移植需求(一样平常利用C 或Java)。
  • 复杂的应用,在必须利用布局化编程的时间(必要变量的范例查抄,函数原型,等等)。
  • 对于影响体系全局性的关键使命应用。
  • 对于安全有很高要求的使命,好比你必要一个结实的体系来防止入侵、破解、恶意粉碎等等。
  • 项目由连串的依靠的各个部门构成。
  • 必要大规模的文件操纵。
  • 必要多维数组的支持。
  • 必要数据布局的支持,好比链表或数等数据布局。
  • 必要产生或操纵图形化界面 GUI。
  • 必要直接操纵体系硬件。
  • 必要 I/O 或socket 接口。
  • 必要利用库大概遗留下来的老代码的接口。
  • 私家的、闭源的应用(shell 脚本把代码就放在文本文件中,全天下都能看到)。
  假如你的应用符合上边的恣意一条,那么就思量一下更强盛的语言吧——大概是Perl、Tcl、Python、Ruby——大概是更高条理的编译语言好比C/C++,大概是Java。纵然云云,你会发现,利用shell来原型开辟你的应用,在开辟步调中也黑白常有效的。


六,第一个shell脚本

打开文本编辑器,新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本实行,见名知意就好,假如你用php写shell 脚本,扩展名就用php好了。
输入一些代码:
#!/bin/bashecho "Hello World !"
  “#!” 是一个约定的标志,它告诉体系这个脚本必要什么表明器来实行,纵然用哪一种Shell。echo下令用于向窗口输出文本。
  运行Shell脚本有两种方法。
作为可实行步伐

  将上面的代码生存为test.sh,并 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告诉体系说,就在当前目次找。
  通过这种方式运行bash脚本,第一行肯定要写对,好让体系查找到精确的表明器。
  这里的"体系",实在就是shell这个应用步伐(想象一下Windows Explorer),但我故意写成体系,是方便明白,既然这个体系就是指shell,那么一个利用/bin/sh作为表明器的脚本是不是可以省去第一行呢?是的。
作为表明器参数

  这种运行方式是,直接运行表明器,其参数就是shell脚本的文件名,如:
/bin/sh test.sh/bin/php test.php
  这种方式运行的脚本,不必要在第一行指定表明器信息,写了也没用。
  再看一个例子。下面的脚本利用 read 下令从 stdin 获取输入并赋值给 PERSON 变量,末了在 stdout 上输出:
#!/bin/bash# Author : mozhiyan# Copyright (c) http://see.xidian.edu.cn/cpp/linux/# Script follows here:echo "What is your name?"read PERSON
echo "Hello, $PERSON"
  运行脚本:
chmod +x ./test.sh
$./test.sh
What is your name?
mozhiyan
Hello, mozhiyan


七,shell变量

 Shell支持自界说变量。
界说变量

  界说变量时,变量名不加美元符号($),如:
variableName="value"
  留意,变量名和等号之间不能有空格,这大概和你认识的全部编程语言都不一样。同时,变量名的定名须遵照如下规则:

  • 首个字符必须为字母(a-z,A-Z)。
  • 中心不能有空格,可以利用下划线(_)。
  • 不能利用标点符号。
  • 不能利用bash里的关键字(可用help下令检察保存关键字)。
  变量界说举例:
myUrl="http://see.xidian.edu.cn/cpp/linux/"myNum=100
利用变量

  利用一个界说过的变量,只要在变量名前面加美元符号($)即可,如:
your_name="mozhiyan"echo $your_name
echo ${your_name}
  变量名表面的花括号是可选的,加不加都行,加花括号是为了资助表明器辨认变量的界限,好比下面这种环境:
for skill in Ada Coffe Action Java
do
echo "I am good at ${skill}Script"done
  假如不给skill变量加花括号,写成echo "I am good at skillScript",表明器就会把skillScript",表明器就会把skillScript当成一个变量(其值为空),代码实行效果就不是我们盼望的样子了。
保举给全部变量加上花括号,这是个好的编程风俗。

重新界说变量

  已界说的变量,可以被重新界说,如:
myUrl="http://see.xidian.edu.cn/cpp/linux/"echo ${myUrl}
myUrl="http://see.xidian.edu.cn/cpp/shell/"echo ${myUrl}
  如许写是正当的,但留意,第二次赋值的时间不能写 myUrl="http://see.xidian.edu.cn/cpp/shell/",利用变量的时间才加美元符(myUrl="http://see.xidian.edu.cn/cpp/shell/",利用变量的时间才加美元符()。
只读变量

  利用 readonly 下令可以将变量界说为只读变量,只读变量的值不能被改变。
  下面的例子实验更改只读变量,效果报错:
#!/bin/bashmyUrl="http://see.xidian.edu.cn/cpp/shell/"readonly myUrl
myUrl="http://see.xidian.edu.cn/cpp/danpianji/"
  运行脚本,效果如下:
/bin/sh: NAME: This variable is read only.
删除变量

  利用 unset 下令可以删除变量。语法:
unset variable_name
  变量被删除后不能再次利用;unset 下令不能删除只读变量。
  举个例子:
#!/bin/shmyUrl="http://see.xidian.edu.cn/cpp/u/xitong/"unset myUrl
echo $myUrl
  上面的脚本没有任何输出。
变量范例

  运行shell时,会同时存在三种变量:

  1) 局部变量

  局部变量在脚本或下令中界说,仅在当前shell实例中有用,其他shell启动的步伐不能访问局部变量。
  2) 情况变量

  全部的步伐,包罗shell启动的步伐,都能访问情况变量,有些步伐必要情况变量来包管其正常运行。须要的时间shell脚本也可以界说情况变量。
  3) shell变量

  shell变量是由shell步伐设置的特别变量。shell变量中有一部门是情况变量,有一部门是局部变量,这些变量包管了shell的正常运行



八,shell特别变量

前面已经讲到,变量名只能包罗数字、字母和下划线,由于某些包罗其他字符的变量有特别寄义,如许的变量被称为特别变量。
  比方,$ 表现当前Shell历程的ID,即pid,看下面的代码:
$echo $$
  运行效果: 29949

特别变量列表变量寄义$0当前脚本的文件名$n通报给脚本或函数的参数。n 是一个数字,表现第几个参数。比方,第一个参数是1,第二个参数是1,第二个参数是2。$#通报给脚本或函数的参数个数。$*通报给脚本或函数的全部参数。$@通报给脚本或函数的全部参数。被双引号(" ")包罗时,与 $* 稍有差别,下面将会讲到。$?上个下令的退出状态,或函数的返回值。$$当前Shell历程ID。对于 Shell 脚本,就是这些脚本地点的历程ID。



九,shell更换

假如表达式中包罗特别字符,Shell 将会举行更换。比方,在双引号中利用变量就是一种更换,转义字符也是一种更换。
  举个例子:
#!/bin/basha=10echo -e "Value of a is $a \n"
  运行效果:
Value of a is 10
  这里 -e 表现对转义字符举行更换。假如不利用 -e 选项,将会原样输出:
Value of a is 10\n
  下面的转义字符都可以用在 echo 中:

转义字符寄义\\反斜杠\a警报,响铃\b退格(删除键)\f换页(FF),将当前位置移到下页开头\n换行\r回车\t程度制表符(tab键) \v垂直制表符  可以利用 echo 下令的 -E 选项克制转义,默认也是不转义的;利用 -n 选项可以克制插入换行符。
下令更换

  下令更换是指Shell可以先实行下令,将输出效果临时生存,在得当的地方输出。
  下令更换的语法:
`command`
  留意是反引号,不是单引号,这个键位于 Esc 键下方。
  下面的例子中,将下令实行效果生存在变量中:#!/bin/bashDATE=`date`
echo "Date is $DATE"USERS=`who | wc -l`
echo "Logged in user are $USERS"UP=`date ; uptime`
echo "Uptime is $UP"

  运行效果:
Date is Thu Jul  2 03:59:57 MST 2009Logged in user are 1Uptime is Thu Jul  2 03:59:57 MST 2009
03:59:57 up 20 days, 14:03,  1 user,  load avg: 0.13, 0.07, 0.15
变量更换

  变量更换可以根据变量的状态(是否为空、是否界说等)来改变它的值。
  可以利用的变量更换情势:

情势阐明${var}变量原来的值${var:word}假如变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。${var:=word}假如变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。${var:?message}假如变量 var 为空或已被删除(unset),那么将消息 message 送到尺度错误输出,可以用来检测变量 var 是否可以被正常赋值。
若此更换出如今Shell脚本中,那么脚本将制止运行。${var:+word}假如变量 var 被界说,那么返回 word,但不改变 var 的值。
  请看下面的例子:
#!/bin/bash echo ${var:-"Variable is not set"}
echo "1 - Value of var is ${var}"echo ${var:="Variable is not set"}echo "2 - Value of var is ${var}"unset varecho ${var:+"This is default value"}echo "3 - Value of var is $var"var="Prefix"echo ${var:+"This is default value"}echo "4 - Value of var is $var"echo ${var:?"Print this message"}echo "5 - Value of var is ${var}"


运行效果:


Variable is not set1 - Value of var isVariable is not set2 - Value of var is Variable is not set3 - Value of var isThis is default value4 - Value of var is Prefix
Prefix5 - Value of var is Prefix



十,shell运算符

Bash 支持许多运算符,包罗算数运算符、关系运算符、布尔运算符、字符串运算符和文件测试运算符。
原生bash不支持简朴的数学运算,但是可以通过其他下令来实现,比方 awk 和 expr,expr 最常用。
expr 是一款表达式盘算工具,利用它能完成表达式的求值操纵。
比方,两个数相加:
#!/bin/bashval=`expr 2 + 2`
echo "Total value : $val"
运行脚本输出:
Total value : 4
两点留意:

  • 表达式和运算符之间要有空格,比方 2+2 是不对的,必须写成 2 + 2,这与我们认识的大多数编程语言不一样。
  • 完备的表达式要被 ` ` 包罗,留意这个字符不是常用的单引号,在 Esc 键下边。
算术运算符

先来看一个利用算术运算符的例子:
#!/bin/sh a=10 b=20
val=`expr $a + $b`
echo "a + b : $val"


运行效果:
a + b : 30
  留意:

  • 乘号(*)前边必须加反斜杠(\)才气实现乘法运算;
  • if...then...fi 是条件语句,后续将会解说。
算术运算符列表运算符阐明举例+加法`expr a+b` 效果为 30。-减法`expr a−b` 效果为 10。*乘法`expr a\**b` 效果为  200。/除法`expr b/a` 效果为 2。%取余`expr ba` 效果为 0。=赋值a=$b 将把变量 b 的值赋给 a。==相称。用于比力两个数字,雷同则返回 true。[ a==b ] 返回 false。!=不相称。用于比力两个数字,不雷同则返回 true。[ a!=b ] 返回 true。
 留意:条件表达式要放在方括号之间,而且要有空格,比方 [a ==b]是错误的,必须写成 [ a ==b ]。

关系运算符

  关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
  先来看一个关系运算符的例子:
#!/bin/sh a=10 b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a is equal to b"
else echo "$a -eq $b: a is not equal to b"
运行效果:
10 -eq 20: a is not equal to b
关系运算符列表运算符阐明举例-eq检测两个数是否相称,相称返回 true。[ a−eqb ] 返回 true。-ne检测两个数是否相称,不相称返回 true。[ a−neb ] 返回 true。-gt检测左边的数是否大于右边的,假如是,则返回 true。[ a−gtb ] 返回 false。-lt检测左边的数是否小于右边的,假如是,则返回 true。[ a−ltb ] 返回 true。-ge检测左边的数是否大即是右边的,假如是,则返回 true。[ a−gea−geb ] 返回 false。-le检测左边的数是否小于即是右边的,假如是,则返回 true。[ a−leb ] 返回 true。布尔运算符

  先来看一个布尔运算符的例子:
#!/bin/sh a=10 b=20 if [ $a != $b ]
then
echo "$a != $b : a is not equal to b"
else echo "$a != $b: a is equal to b"
  运行效果:
10 != 20 : a is not equal to b
布尔运算符列表运算符阐明举例!非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。-o或运算,有一个表达式为 true 则返回 true。[ a−lt20-ob -gt 100 ] 返回 true。
-a与运算,两个表达式都为 true 才返回 true。[ a−lt20−ab -gt 100 ] 返回 false。字符串运算符

  先来看一个例子:
#!/bin/sh a="abc" b="efg" if [ $a = $b ]
then
echo "$a = $b : a is equal to b" else
echo "$a = $b: a is not equal to b"

  运行效果:
abc = efg: a is not equal to b
字符串运算符列表运算符阐明举例=检测两个字符串是否相称,相称返回 true。[ a=b ] 返回 false。!=检测两个字符串是否相称,不相称返回 true。[ a!=b ] 返回 true。-z检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。-n检测字符串长度是否为0,不为0返回 true。[ -z $a ] 返回 true。str检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。文件测试运算符

  文件测试运算符用于检测 Unix 文件的各种属性。  比方,变量 file 表现文件“/var/www/tutorialspoint/unix/test.sh”,它的巨细为100字节,具有 rwx 权限。下面的代码,将检测该文件的各种属性:
#!/bin/sh file="/var/www/tutorialspoint/unix/test.sh"
if [ -r $file ]
then
echo "File has read access"
else echo "File does not have read access"
  运行效果:
File has read access


文件测试运算符列表操纵符阐明举例-b file检测文件是否是块装备文件,假如是,则返回 true。[ -b $file ] 返回 false。-c file检测文件是否是字符装备文件,假如是,则返回 true。[ -b $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。

文章参考出处:
http://www.cnblogs.com/maybe2030/
相干阅读:
技能:亿级日记及时分析平台,一个码农半小时就可以搞定,只因ELK
分享:2T架构师学习资料干货分享
顶层:使用顶层框架,秒变微服务专家
履历:那些年不加班的开辟团队的机密,缘故原由竟是由于连续集成
nrVPJ4kPPA900rO3.jpg DNU6Z8b2fa66qm8G.jpg 架构师小秘圈,聚集10万架构师的小圈子!不定期分享技能干货,行业秘闻!搜集各类奥妙好玩的话题和盛行动向!长按左侧图片扫码参加微信群!




上一篇:【连载】嵌入式Linux开辟教程:Linux Shell
下一篇:Shell脚本视频教程
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

 

QQ|申请友链|小黑屋|手机版|Hlshell Inc. ( 豫ICP备16002110号-5 )

GMT+8, 2024-5-15 23:23 , Processed in 0.091011 second(s), 47 queries .

HLShell有权修改版权声明内容,如有任何爭議,HLShell將保留最終決定權!

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表