1.什么是 Shell 脚本
例子
让我们看一个例子:
/bin/sh #!/bin/sh 复制代码
光盘〜
建立目录
光盘
对于((i=0;i
触摸测试_$i.txt
完毕
示例解释
第 1 行:指定脚本解释器。这里使用 /bin/sh 作为解释器。
第2行:切换到当前用户的主目录
第 3 行:创建目录
第 4 行:更改目录
第5行:循环条件,共10次循环
第 6 行:创建 ...9.txt 文件
第 7 行:循环体结束
mkdir和touch是系统内置程序,一般在/bin或者/usr/bin目录下。for、do、done是sh脚本语言的关键字。
shell和shell脚本的概念
Shell 是一个提供接口的应用程序,通过它用户可以访问操作系统内核的服务。Ken 的 sh 是第一个 Unix Shell,也是一个典型的图形界面 Shell。
Shell脚本(shell)是针对shell编写的脚本程序。业界通常指shell脚本,但读者要知道shell和shell是两个不同的概念。出于习惯和简洁考虑,本文中的“shell编程”均指shell脚本编程,而非shell本身的开发(如扩展开发)。
2. 环境
Shell编程和Java、PHP编程一样,只需要一个可以编写代码的文本编辑器和一个可以解释执行代码的脚本解释器。
操作系统
目前主流操作系统均支持 shell 编程,本文所讲的 shell 编程指的是 Linux 下的 shell,基本讲的是 POSIX 标准下的功能,因此同样适用于 Unix 和 BSD(如 Mac OS)。
Linux
Linux 默认安装时带有一个 shell 解释器。
苹果系统
Mac OS不仅自带了sh、bash两个最基本的解释器,还内置了ksh、csh、zsh等不太常用的解释器。
模拟器开启
出厂时没有内置shell解释器,需要自行安装,为了能同时使用grep、awk、curl等工具,最好安装一个或者mingw来模拟linux环境。
脚本解释器
什
即shell,POSIX()标准的shell解释器,它的二进制文件路径通常为/bin/sh,由贝尔实验室开发。
本文讲的是sh,如果使用其他语言进行shell编程,请参考对应语言的文档。
狂欢
Bash 是 shell 的替代品,属于 GNU,二进制文件路径一般为 /bin/bash,业界经常会把 bash、sh、shell 混用,比如在招聘运维工程师的文案中经常会看到:熟悉 Linux Bash 编程,精通 Shell 编程。
在中,/bin/sh 是指向 /bin/bash 的符号链接:
[root@ ~]# ls -l /bin/*sh
-rwxr-xr-x。 1 root root 2月22日 05:09 /bin/bash
-rwxr-xr-x。 1 root root 2012 年 10 月 17 日 /bin/dash
. 1 root root 4 3月22日 10:22 /bin/sh -> bash
但在 Mac OS 上并非如此,/bin/sh 和 /bin/bash 是两个不同的文件,尽管它们的大小仅相差约 100 字节:
iMac:〜$ ls -l / bin / * sh
-r-xr-xr-x 1 根轮 6 十一月 16:52 /bin/bash
-rwxr-xr-x 2 根轮 6 十一月 16:52 /bin/csh
-r-xr-xr-x 1 根轮 6 十一月 16:52 /bin/ksh
-r-xr-xr-x 1 根轮 6 十一月 16:52 /bin/sh
-rwxr-xr-x 2 根轮 6 十一月 16:52 /bin/tcsh
-rwxr-xr-x 1 根轮 6 十一月 16:52 /bin/zsh
高级编程语言
理论上,只要一种语言提供了解释器(而不仅仅是编译器),该语言就可以用于脚本编写。常见的解释型语言都可以用于脚本编写,例如 Perl、Tcl、PHP 和 Ruby。Perl 是最古老的脚本语言,近年来已成为一些 Linux 发行版的默认解释器。
编译型语言只要有解释器,同样可以用于脚本编写。例如C shell 是内置的(/bin/csh),Java 有第三方解释器,Ada 有付费解释器。
3.如何选择shell编程语言
简单与高级
如果你觉得用自己熟悉的语言(比如Java,C)编写shell脚本太过冗长,而你只想做一些诸如备份文件、安装软件、下载数据等操作,那么学习使用sh或者bash会是一个不错的选择。
Shell 只定义了一种非常简单的编程语言,所以如果你的脚本比较复杂,或者要操作的数据结构比较复杂,你还是应该使用 Perl 之类的脚本语言,或者你已经擅长的高级语言。因为 sh 和 bash 在这方面比较弱,例如:
其函数只能返回字符串,而不能返回数组。
它不支持面向对象的设计,因此你无法实现一些优雅的设计模式
它是解释执行同时进行的,甚至不像PHP那样经过预编译,如果你的脚本包含错误(例如调用了不存在的函数),只要这一行没有被执行,就不会报错。
环境兼容性
如果你的脚本是提供给其他用户使用的,使用 sh 或者 bash,你的脚本会有最好的环境兼容性。Perl 早已是 Linux 的标准功能,近年来也成为一些 Linux 发行版的标准功能。至于 Mac OS,它默认安装了 Perl、Ruby、PHP、Java 等主流编程语言。
4.第一个 shell 脚本
1. 写作
打开文本编辑器并创建一个扩展名为 sh 的新文件(sh 代表 shell)。扩展名不会影响脚本的执行,因此名称是不言自明的。如果您使用 php 编写 shell 脚本,请使用扩展名 php。
输入一些代码,第一行通常是这样的:
/bin/bash #!/bin/bash
/usr/bin/php 的 #!
“#!”是一个常规标记,它告诉系统执行该脚本需要什么解释器。
2. 运行
运行 Shell 脚本有两种方式:
作为可执行程序
chmod +x 测试.sh
./测试.sh
注意,必须写成 ./test.sh,而不是 test.sh。运行其他二进制程序时也一样。如果直接写 test.sh,Linux 系统会在 PATH 中查找名为 test.sh 的程序。PATH 中只有 /bin、/sbin、/usr/bin、/usr/sbin 等。当前目录通常不在 PATH 中,因此如果写成 test.sh,则找不到该命令。必须使用 ./test.sh 来告诉系统在当前目录中查找。
以这种方式运行 bash 脚本时,第一行必须正确书写,以便系统能够找到正确的解释器。
这里的“系统”其实就是 shell 应用程序(想象一下),不过我为了方便理解,故意写成了 。既然 指的是 shell,那么使用 /bin/sh 作为解释器的脚本,是否可以省略第一行呢?可以。
作为解释器参数
这种运行方式是直接运行解释器,其参数是shell脚本的文件名,如:
/bin/sh 测试.sh
/bin/php 测试.php
这样运行脚本的时候,就没必要在第一行指定解释器信息了,而且这么做也没用。
5. Shell 变量
在Shell编程中,可以使用变量,充分体现了它的灵活性。对于Shell来说,所有变量的值都是字符串。在Shell脚本中主要有以下几种变量:
系统变量
环境变量
用户变量
1.系统变量
以下是一些常用的Shell系统变量及其含义:
$#:获取命令行参数的数量
$0:获取当前程序名称
$*: 获取所有命令行参数(以字符串形式)
$@:获取所有命令行参数(以字符串数组的形式)
$n:获取命令行的第n个参数
2.环境变量
Shell 环境变量是所有 Shell 程序都接受的参数,Shell 程序运行时会接受一组变量,这些变量就是环境变量,常用的 Shell 环境变量有以下几种:
$PATH:决定shell将在哪个目录中寻找命令或程序(参见环境变量的配置)
$HOME:当前用户主目录的完整路径名
$: 历史记录数
$: 当前用户的登录名
$SHELL: 当前用户 Shell 类型
$:指主机名
$UID:获取当前用户的ID
$PWD:当前工作目录的绝对路径名
* 可以通过 echo 和 unset 显示和设置环境变量
* env 可以显示所有环境变量
3. 用户变量
3.1 定义变量
定义变量时,变量名前不要包含美元符号 ($),例如:
=“qinjx”
注意变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。
除了显式的直接赋值外,还可以使用语句给变量赋值,比如:
对于文件‘ls /etc’
/
还是同样的功能,就是声明变量的类型。
[-aixr]
-a:将变量定义为数组类型
-i:将变量定义为整数类型
-x:将变量定义为环境变量
-r:设置变量类型
3.2 使用变量
要使用定义的变量,只需在变量名前面添加一个美元符号,例如:
=“qinjx”
回显 $
回显 ${}
变量名周围的花括号是可选的。它们是为了帮助解释器识别变量的边界而添加的,例如以下情况:
掌握 Ada Coffe Java 技能;
echo "我擅长${skill}"
完毕
如果我们不在skill变量上加花括号,直接写echo "I am good at $",那么解释器就会把$当成一个变量(其值为空),代码执行的结果就不是我们所期望的了。
建议所有变量都加上花括号,这是一个好的编程习惯,在IDEA中写shell的时候,IDE会提示你加上花括号。
3.3 重新定义变量
已定义的变量可以重新定义,如:
=“qinjx”
回显 $
=“”
回显 $
这是合法的,但请注意,第二次赋值时不能写 $=""。只有在使用变量时才会添加美元符号。
3.4 变量键盘读数
读
读 [-pt]
-p:后面可以跟提示符
-t:等待的秒数
例如:
read -p “输入你的名字” -t 30 named
6. 注意事项
以“#”开头的行是注释,将被解释器忽略。
多行注释
sh 中没有多行注释,只能在每行添加一个 # 符号。如下所示:
##### 用户配置区域开始#####
# 项目根目录,建议把这个脚本放在项目根目录下,这里不用改。
# 应用程序名称,确保与Xcode中的.app名称一致
##### 用户配置区域结束#####
如果在开发过程中需要临时注释掉一大段代码,之后再取消注释,该怎么办呢?每行都加一个#号太麻烦了。可以将需要注释掉的代码用一对花括号括起来,定义成一个函数,如果没有地方调用这个函数,代码就不会被执行,达到和注释一样的效果。
7. 字符串
字符串是shell编程中最常用、最有用的数据类型(除了数字和字符串,就没别的有用类型了,哈哈)。字符串可以用单引号、双引号、不用引号引起来,单引号和双引号的区别跟PHP类似。
撇号
str = '这是一个'
单引号字符串的限制:
单引号中的任何字符都将按原样输出,单引号字符串中的变量无效。
单引号字符串中不能出现单引号(即使使用单引号转义字符)
双引号
='qinjx'
str="您好,我知道您的是 \"$\"!\n"
双引号可以包含变量
转义字符可以出现在双引号中
字符串操作
连接字符串
=“qinjx”
=“你好,“$”!”
=“你好,${}!”
回显 $$
获取字符串的长度
=“abcd”
echo ${#} #输出:4
提取子字符串
=“非常棒”
echo ${:1:4} #输出:liba
查找子字符串
=“非常棒”
echo `expr index "$" is`#输出:3,这条语句的意思是:找出这个句子中字母i的位置,在Linux下运行,在Mac下会报错
8. 流程控制语句
与Java、PHP等语言不同,sh的流程控制不能为空,如:
如果 (isset($_GET["q"])) {
(问);
别的 {
//做
而在sh/bash中则不是这样,如果else分支中没有执行的语句,就不要写这个else。
另外注意,sh 中 if [ $foo -eq 0 ] 中的方括号和 Java/PHP 中 if 后面的圆括号有很大区别。它是一个可执行程序(就像 ls 和 grep 一样)。很意外吧?在系统中,它位于 /usr/bin 目录中:
ll /usr/bin/[
-rwxr-xr-x。 1 root root 33408 2012 年 6 月 22 日 /usr/bin/[
因为这里的方括号是可执行程序,所以方括号后面必须有一个空格。不能写成 if [$foo -eq 0]
1. 如果不是
如果
如果
然后
...
菲
用一行写一遍(适合终端命令提示符):
如果`ps -ef | grep ssh`;则 echo hello;fi
末尾的 fi 是 if 的倒写形式。你会遇到类似的
如果别的
如果
然后
...
别的
菲
否则-否则
如果
然后
elif
别的
菲
2. 一会儿
为了
开头的例子已经证明了这一点:
对于 item1 item2 中的 var ... itemN
做
...
完毕
写成一行:
对于 item1 item2 中的 var...itemN;执行;…完成;
C 风格
对于((EXP1;EXP2;EXP3))
做
完毕
尽管
尽管
做
完毕
无限循环
尽管 :
做
完毕
或者
虽然正确
做
完毕
或者
为了 (( ; ; ))
直到
直到
做
完毕
3. 案例
案例“${opt}”
“--”)
1 美元
出口
;;
“--”)
1 美元
出口
;;
“--”)
出口
;;
“--”)
出口
;;
“出口” )
出口
;;
*)回显“又糟糕了”
埃萨克
case 的语法与 C 的语法非常不同。它需要一个 esac(反转大小写)作为结束标记,每个 case 分支需要一个右括号,以及两个分号来表示中断。
9. 重定向
标准输入:代码为 0,使用
标准输出:代码为1,使用>或>>;
标准错误输出:代码为2,使用2>或2>>;
如果您想将正确和不正确的数据写入同一个文件,请使用&>。
输出:
可以将命令的输出保存到文件中,如果该文件不存在,系统会自动创建。
如果使用>,则会覆盖原始文件;
如果使用>>,它将被添加到文件末尾。
进入:
原本需要键盘输入的数据被文件内容所取代。
10. 订单执行的判断依据
当我们需要一次执行多个命令时,我们有以下方法:
命令;命令
一次可以执行多条命令,但是不考虑命令间的相关性,即前一条命令不能影响后面的命令是否执行。
使用 && 或 ||
如果命令执行结果正确,在Linux下会返回$?=0的值(命令返回码);
我们可以使用逻辑运算符&&和||来进行判断:
命令1 && 命令2
如果cmd1被正确支持,则执行cmd2,否则不会执行;
命令1 || 命令2
如果cmd1支持错误,则执行cmd2,否则不会执行;
11. 管道命令
管道命令“|”可以将前一个命令的正确信息作为输入传递给下一个命令。
常用的管道命令:
1. 切割
分解同一行的数据,以分析某些数据或文本
2. grep
使用正则表达式分析一行数据
3. 排序
它帮助我们分类
4. uniq
重复数据删除
5. 厕所
有关计算输出的信息
6. 发球座
同时将数据传输到文件和屏幕
7. tr
删除或替换消息中的文本
8.
将 Tab 键转换为空格键
9. 分裂
将大文件拆分为较小的文件
10.xargs
使用空格作为分隔符来生成命令的参数
12. 文件包含
您可以使用 and . 关键字,例如:
./.sh
。 ./.sh
在bash中,和是等价的,都是读取.sh的内容并执行(类似PHP),为了更好的移植性,建议使用第二种写法。
包含文件与执行文件相同。您还需要写入文件的路径,而不仅仅是文件名。例如,在上面的例子中:
。 ./.sh
你不能写:
. .sh
如果.sh是用户传入的参数,那么如何获取其绝对路径呢?方法是:
=` -f $1`#$1为用户输入的参数,如.sh
。 $
13. 功能
函数是存储在内存中的一组代码的命名元素。
该函数的语法结构为:
{
我们使用位置参数 $1 来接收命令行中传递的参数。请注意,$1 括在花括号中。
Shell 脚本从上到下执行,如果一个函数调用另一个函数,那么被调用的函数必须在调用函数之前定义。
当然,函数除了传递参数之外,还可以有返回值。默认情况下,在执行完函数中最后一行代码后,方法会返回一个状态号。可以使用 $? 变量来查看函数执行的状态。返回值为 0 表示方法正常退出。非零表示程序出错或者其他异常退出。
我们使用关键字返回一个整数。这里有两点需要注意:
函数执行后会返回一个状态码,状态码范围是0~255。
如果不想返回函数的状态码,而是想返回字符串或者其他类型,可以使用echo变量来返回值。
參考
扫一扫在手机端查看
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。