Mac下Shell脚本使用

2,105 阅读6分钟
原文链接: www.jianshu.com

【原创博文,转载请注明出处!】
准备学习下Shell命令,俗话说“好记性不如烂笔头”,做点笔记方便以后查找。详细学习途径请移步 --> Shell菜鸟教程

(一) Shell环境

Shell常识脑补
① Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

② Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

③ Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。

④ Shell 脚本(shell script),是一种为 shell 编写的脚本程序。

⑤ 业界所说的 shell 通常都是指 shell 脚本,但读者朋友要知道,shell 和 shell script 是两个不同的概念。

⑥一般 新建一个文件扩展名为 sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用 php 写 shell 脚本,扩展名就用 php 好了。

由于习惯的原因,简洁起见,本文出现的 "shell编程" 都是指 shell 脚本编程,不是指开发 shell 自身。
创建一个Shell脚本(test.sh)

打开终端 -->cd到脚本要存放的位置 (如:我想在桌面上创建一个Shell文件夹,并在该文件夹里新建一个test.sh的脚本文件)。
使用文本编辑器(Xcode,CS Code等其他编辑器都可以)打开test.sh,并加入如下两行code:

#!/bin/bash
echo "Hello World !"

"#!" 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
"echo" 命令用于向窗口输出文本。

Shell脚本执行方式

1、作为可执行程序
将上面的代码保存为 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 告诉系统说,就在当前目录找。

2、作为解释器参数

这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:

/bin/sh test.sh
/bin/php test.php

这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

下面我们尝试用方法1在终端执行test.sh脚本,成功运行会输出“Hello World!”。
将上面的代码保存好,并在终端 cd 到相应目录(即Shell的位置)

终端执行脚本指令.jpg

可以看到成功地输出了“Hello World! ”(当然方法2更简单,不需要指定脚解释器信息,写了也没用)。如果不想这么麻烦,直接看到“Hello World!”,你也可以在终端直接输入 echo "Hello World"嘛,但是终端毕竟不是我等凡夫俗子能驾驭的

(二) Shell基本语法

A.变量

示例:定义一个变量名name并赋值为Rephontil

name="Rephontil"

需要注意的是:变量名和等号之间不能有空格,这与我们之前熟悉的所有编程语言都不一样(足以奇葩)。

使用变量,只要在变量名前面加美元符号即可,如:

name="Rephontil"
方式one  --->   echo $name
方式two  --->   echo ${name}

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

studentName="小明"
方式1  --->  echo "那位调皮的同学叫${studentName}"
方式2  --->  echo "那位调皮的同学叫$studentName"

方式1 成功显示“那位调皮的同学叫小明”
方式2 成功显示“那位调皮的同学叫studentName”。这显然
总结:Shell编程推荐给所有变量加上花括号,这是个好的编程习惯。

B.数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小
类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。

定义数组
在Shell中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:数组名=(值1 值2 ... 值n)
如:nameArr=("football" "足球" "篮球" "羽毛球")
读取数组
读取数组元素值的一般格式是:
{数组名[下标]} 如:echo{nameArr[0]} -> football
使用@符号可以获取数组中的所有元素,例如:
echo ${nameArr[@]} -> football 足球 篮球 羽毛球

获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
length=${#array_name[n]}

C.注释

以"#"开头的行就是注释,会被解释器忽略。

sh里没有多行注释,只能每一行加一个#号。
如果在开发过程中,遇到大段的代码需要临时注释起来,过一会儿又取消注释,怎么办呢?

每一行加个"#"符号太费力了,可以把这一段要注释的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释一样的效果。

D.传递参数

我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……

echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";

在终端执行脚本后log如下(1 2 3为我们传入的3个参数):
Rephontil:Shell zhouyong$ /bin/sh test.sh 1 2 3
Shell 传递参数实例!
执行的文件名:test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3

注:其中 $0 为执行的文件名。
另外,还有几个特殊字符用来处理参数,下表所列:


几个特殊字符用来处理参数.png

说明:怎么看* 与@ 区别?

相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。

# ①  $*
for i in "$*"; do
echo $I
done

# ②  $@
for i in "$@"; do
echo $I
done

①结果为: 1 2 3
②结果为:
1
2
3
明显看出:①结果为一个整体  ②结果保持传进去的独立个体

E.Shell 基本运算符

Shell 和其他编程语言一样,支持多种运算符,包括:

算数运算符
关系运算符
布尔运算符
字符串运算符
文件测试运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

例如,两个数相加(注意使用的是反引号 ` 而不是单引号 '):
注意要点:

a.表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
b.完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。

算术运算符表
算术运算符表.jpg
注意:条件表达式要放在方括号之间,并且要有空格,例如: [a==b] 是错误的,必须写成 [ a ==b ]。

关系运算符
关系运算符.jpg

布尔运算符
布尔运算符.png

逻辑运算符
逻辑运算符.png

字符串运算符
字符串运算符.png

文件测试运算符
文件测试运算符.png
图片发自简书App