Shell 脚本编程总结及速查手册

Shell是一种编程语言, 它像其它编程语言如: C, Java, Python等一样也有变量/函数/运算符/if语句/循环控制/… 但在开始之前, 我想先理清Shell语言与Shell之间的关系.

Shell与Shell语言

上面说了Shell是一种编程语言但你可能也听说过: sh/bash/csh/zsh/…它们也叫Shell, 实际上这里所说的Shell是一种应用程序, 它负责解释执行你编写的Shell脚本, Mac默认就自带了sh/bash/csh/zsh/tcsh/ksh, 你可以这样查看cat /etc/shells 不同的shell的用法基本相同, 但有些shell提供了一些新特性, 比如我现在在用的就是zsh, 更多zsh的内容可以去看这篇文章

第一个Shell脚本

依国际惯例这里以在终端里打印一句hello shell!开始, 第一行的#!是一个约定标记, 它告诉脚本这段脚本需要什么解释器来执行. 第二行的echo命令则负责向屏幕上输出一句话.

如何运行

运行shell程序有3种方法:

  1. chmod +x使文件具有可执行权限, 直接运行
  2. 直接调用解释器, 将脚本文件作为参数传入 (比如bash hi.sh)
  3. 使用source(也可用 . 代替)执行文件

通常情况下, 最方便的方式就是方式1, 通过方式1执行你需要在脚本第一行写好这段脚本由哪个解释器来解释, 而通过方式2来执行则没有这个限制, 写了也没用. 除此之外方式1与方式2执行命令就没有区别了, 但方式3执行的方式与前两种都不同:

使用source执行shell脚本时, 不会创建子进程, 而是在父进程中直接执行!

这里不作更多解释, 感兴趣的同学可以去参考Linux Shell编程从入门到精通这本书的第一章的相关部分.

变量

和其它语言一样Shell中也有变量, 而且更简单, 但有一些比较特殊的地方.

  1. Shell中的变量只有字符串这一种类型
  2. Shell中变量名与变量值没有长度限制
  3. Shell的变量也允许比较操作和整数操作, 只要变量中的字符串为数字

定义变量

需要注意: = 两边不能加空格, 当赋值语句包含空格时请加引号(单引号/双引号均可)比如: 1

variable_name="ghui's blog"
复制代码

Shell中的变量可以分为两种类型:

  1. 局部变量 (定义变量时在前面加local修饰符)
  2. 全局变量 (定义变量时不加任何修饰符)

与其它语言一样局部变量的可见范围是代码块或函数内, 全局变量在全局范围内可见.看个简单的例子:


num=111 
func1()
{
  local num=222 
  echo $num
  }
echo "before---$num"
func1
echo "after---$num"
复制代码

输出:

before---111
222
after---111
复制代码

使用变量

使用一个定义过的变量, 只要在变量名前面加$即可, 如:

name=ghui
echo $name
echo ${name} 
复制代码

在使用变量时还有一个地方需要注意, 请看下面的例子:


str='abc'
echo "1 print $str"
echo '2 print $str'
复制代码

输出:

 print abc
2 print $str
复制代码

即: 被双引号括起来的变量会发生变量替换, 单引号不会

注释

Shell中注释使用#, 而且它不支持多行注释.

常用的字符串操作

字符串拼接

name="shell"
sayHi="hello, "$name" !"
sayHi2="hello, ${name} !"
echo $sayHi $sayHi2
复制代码

注意: 上面说的单双引号引起的变量替换问题

获得字符串长度

string="abcd"
echo ${#string} 
复制代码

截取字符串

str="hello shell"
echo ${str:2}  
echo ${string:1:3} 
复制代码

更多关于字符串的操作可以看这个

if/else流程控制

基本语法结构:

if condition
then 
	 do something
	 elif condition
then 
	do something
	elif condition
then 
	do something
	else
	do something
	fi
复制代码

其中, elif语句和else语句非必须的.看个例子:


a=1
if [ $1=$a ]
then
	echo "you input 1"
	elif [ $1=2 ]
then
	echo "you input 2"
	else
	echo " you input $1"
	fi
复制代码

很简单, 不过这里有两个地方需要注意, 如果某个条件下的执行体为空, 则你就不能写这个条件 即下面这样会报错:

if condition
then 
	#do nothing
	elif condition
then 
	# do nothing
	#or
else
	#do nothing
	复制代码

另外, [ ] 两边一定要加空格, 下面这样都会报错:

if [$a=$b]
#or 
if [ $a=$b]
#or 
if [$a=$b ]
复制代码

只有这样if [ $a=$b ]才是对的. 注意: 实际上这里的[]test命令的一种形式, [是系统的一个内置命令,存在路径是/bin/[,它是调用test命令的标识, 右中括号是关闭条件判断的标识, 因此下面的两个测试语句是等效的:

if test "2>3"
then
	...
	fi
复制代码

if [ "2>3" ]
then 
	...
	fi
复制代码

[]之外, shell语言中还有几种其它括号, 比如: 单小括号/双小括号/双中括号/… , 不同的括号有不同的用法, 更多关于shell中, 括号的用法可以看看这个

switch流程控制

当条件较多时, 可以选择使用switch语句, shell中的switch语句的写法和其它语言还是有些不同的, 基本结构如下:

case expression in
	pattern1)
		do something... ;;
	pattern2)
		do something... ;;
	pattern2)
		do something... ;;
	...
	esac
复制代码

看个例子:


input=$1
case $input in
        1 | 0)
        str="一or零";;
        2)
        str="二";;
        3)
        str="三";;
        *)
        str=$input;;
        esac
echo "---$str"
复制代码

这个例子会根据你执行此脚本时传入的参数不同在屏幕上输出不同的值, 其中第一个case 1 | 0代表逻辑或. NOTE:

  1. ;;相当于其它语言中的break
  2. 每个pattern之后记得加)
  3. 最后记得加esac (即反的case)

for循环

基本结构:

for name [in list]
do
	...
	done
复制代码

其中,[]括起来的 in list, 为可选部分, 如果省略in list则默认为in "$@", 即你执行此命令时传入的参数列表. 看个例子:

for file in *.txt
do
	open $file
	done
复制代码

遍历当前目录下的所有txt文件, 并依次打开.

while循环

基本结构:

while condition
do
	do something...
	done
复制代码

看个例子:


i=0
while ((i
do
	((i++))
	echo "i=$i"
	done
复制代码

输出:

NOTE: 你可能需要去了解一下(())的用法

until循环

基本结构

until condition
do
	do something...
	done
复制代码

看个例子:


i=5
until ((i==0))
do
	((i--))
	echo "i=$i"
	done
复制代码

输出:

跳出循环

shell中也支持break跳出循环, continue跳出本次循环.用法与C, Java中相同

函数

要定义一个函数, 可以使用下面两种形式:

function funcname()
{
	do something
	}
复制代码

或者

funcname ()
{
	do something
	}
复制代码

看个例子


add()
{
	let "sum=$1+$2"
	return $sum
	}
add $1 $2
echo "sum=$?"
复制代码

输入

输出

其中, $?在shell中保存的是上一条命令的返回值

NOTE:

  1. 函数必须先定义后使用
  2. 如果在函数中使用exit会退出脚本, 如果想退回到原本函数调用的地方, 则可使用return

向脚本传递参数

先shell脚本传递参数, 非常简单, 只需要在你执行命令的后面跟上即可, 看个例子:


echo "$# parameters";
echo "$@";
echo "$0"
echo "$1"
复制代码

输入:

输出:

2 parameters
11 22
test.sh
11
复制代码

解释: $@代表所有参数的内容, $#代表所有参数的个数, $0代表脚本的名称, $1代表第一个参数的值.

后记

之所以要写这篇博客, 有以下几个原因:

  1. 想总结一下shell编程中的关键知识点, 方便日后查看.
  2. 想通过shell优化一下我的hexo写作及博客管理流程, 目前相关脚本已完成, 待我下一篇博客分享给大家, 如果你也是在用Hexo写博客, 相信对你会很有用, 尽请期待!
  3. 可以看的出这里总结的都是最关键的知识点, 还有很多这里并没有说. 是因为我觉得刚开始学习一个东西没必要太计较一些细节/琐碎的东西, 掌握好大致知识框架, 然后在大家编写具体的脚本时, 遇到具体问题, 再去google寻找即可.

参考

  1. Shell脚本编程30分钟入门
  2. Linux Shell编程从入门到精通

Shell是一种编程语言, 它像其它编程语言如: C, Java, Python等一样也有变量/函数/运算符/if语句/循环控制/… 但在开始之前, 我想先理清Shell语言与Shell之间的关系. Shell与Shell语言 上面说了Shell是一种编程语言但你可能也听说过: sh/bash/csh/zsh/…它们也叫Shell, 实际上这里所说的Shell是一种应用程序, 它负责解释执行你编写的Shell脚本, Mac默认就自带了sh/bash/csh/zsh/tcsh/ksh, 你可以这样查看cat /etc/shells 不同的shell的用法基本相同, 但有些shell提供了一些新特性, 比如我现在在用的就是zsh, 更多zsh的内容可以去看这篇文章 第一个Shell脚本 依国际惯例这里以在终端里打印一句hello shell!开始, 第一行的#!是一个约定标记, 它告诉脚本这段脚本需要什么解释器来执行. 第二行的echo命令则负责向屏幕上输出一句话. 如何运行 运行shell程序有3种方法: chmod +x使文件具有可执行权限, 直接运行 直接调用解释器, 将脚本文件作为参数传入 (比如bash hi.sh) 使用source(也可用 . 代替)执行文件 通常情况下, 最方便的方式就是方式1, 通过方式1执行你需要在脚本第一行写好这段脚本由哪个解释器来解释, 而通过方式2来执行则没有这个限制, 写了也没用. 除此之外方式1与方式2执行命令就没有区别了, 但方式3执行的方式与前两种都不同: 使用source执行shell脚本时, 不会创建子进程, 而是在父进程中直接执行! 这里不作更多解释, 感兴趣的同学可以去参考Linux Shell编程从入门到精通这本书的第一章的相关部分. 变量 和其它语言一样Shell中也有变量, 而且更简单, 但有一些比较特殊的地方. Shell中的变量只有字符串这一种类型 Shell中变量名与变量值没有长度限制 Shell的变量也允许比较操作和整数操作, 只要变量中的字符串为数字 定义变量 需要注意: = 两边不能加空格, 当赋值语句包含空格时请加引号(单引号/双引号均可)比如:


variable_name="ghui's blog"
复制代码

Shell中的变量可以分为两种类型: 局部变量 (定义变量时在前面加local修饰符) 全局变量 (定义变量时不加任何修饰符) 与其它语言一样局部变量的可见范围是代码块或函数内, 全局变量在全局范围内可见.看个简单的例子:


num=111 
func1()
{
  local num=222 
  echo $num
  }
echo "before---$num"
func1
echo "after---$num"
复制代码

输出:


before---111
222
after---111
复制代码

使用变量 使用一个定义过的变量, 只要在变量名前面加$即可, 如:


name=ghui
echo $name
echo ${name} 
复制代码

在使用变量时还有一个地方需要注意, 请看下面的例子:


str='abc'
echo "1 print $str"
echo '2 print $str'
复制代码

输出:


 print abc
 print $str
复制代码

即: 被双引号括起来的变量会发生变量替换, 单引号不会 注释 Shell中注释使用#, 而且它不支持多行注释. 常用的字符串操作 字符串拼接


name="shell"
sayHi="hello, "$name" !"
sayHi2="hello, ${name} !"
echo $sayHi $sayHi2
复制代码

注意: 上面说的单双引号引起的变量替换问题 获得字符串长度


string="abcd"
echo ${#string} 
复制代码

截取字符串


str="hello shell"
echo ${str:2}  
echo ${string:1:3} 
复制代码

更多关于字符串的操作可以看这个 if/else流程控制 基本语法结构:


if condition
then 
	 do something
	 elif condition
then 
	do something
	elif condition
then 
	do something
	else
	do something
	fi
复制代码

其中, elif语句和else语句非必须的.看个例子:


a=1
if [ $1=$a ]
then
	echo "you input 1"
	elif [ $1=2 ]
then
	echo "you input 2"
	else
	echo " you input $1"
	fi
复制代码

很简单, 不过这里有两个地方需要注意, 如果某个条件下的执行体为空, 则你就不能写这个条件 即下面这样会报错:


if condition
then 
	#do nothing
	elif condition
then 
	# do nothing
	#or
else
	#do nothing
复制代码

另外, [ ] 两边一定要加空格, 下面这样都会报错:


if [$a=$b]
#or 
if [ $a=$b]
#or 
if [$a=$b ]
复制代码

只有这样if [ $a=$b ]才是对的. 注意: 实际上这里的[]是test命令的一种形式, [是系统的一个内置命令,存在路径是/bin/[,它是调用test命令的标识, 右中括号是关闭条件判断的标识, 因此下面的两个测试语句是等效的:


if test "2>3"
then
	...
	fi
复制代码

	

if [ "2>3" ]
then 
	...
	fi
复制代码

除[]之外, shell语言中还有几种其它括号, 比如: 单小括号/双小括号/双中括号/… , 不同的括号有不同的用法, 更多关于shell中, 括号的用法可以看看这个 switch流程控制 当条件较多时, 可以选择使用switch语句, shell中的switch语句的写法和其它语言还是有些不同的, 基本结构如下:


case expression in
	pattern1)
		do something... ;;
	pattern2)
		do something... ;;
	pattern2)
		do something... ;;
	...
	esac
复制代码

看个例子:


input=$1
case $input in
        1 | 0)
        str="一or零";;
        2)
        str="二";;
        3)
        str="三";;
        *)
        str=$input;;
        esac
echo "---$str"
复制代码

这个例子会根据你执行此脚本时传入的参数不同在屏幕上输出不同的值, 其中第一个case 1 | 0代表逻辑或. NOTE: ;;相当于其它语言中的break 每个pattern之后记得加) 最后记得加esac (即反的case) for循环 基本结构:


for name [in list]
do
	...
	done
复制代码

其中,[]括起来的 in list, 为可选部分, 如果省略in list则默认为in "$@", 即你执行此命令时传入的参数列表. 看个例子:


for file in *.txt
do
	open $file
	done
复制代码

遍历当前目录下的所有txt文件, 并依次打开. while循环 基本结构:


while condition
do
	do something...
	done
复制代码

看个例子:


i=0
while ((i
do
	((i++))
	echo "i=$i"
	done
复制代码

输出: NOTE: 你可能需要去了解一下(())的用法 until循环 基本结构


until condition
do
	do something...
	done
复制代码

看个例子:


i=5
until ((i==0))
do
	((i--))
	echo "i=$i"
	done
复制代码

输出: 跳出循环 shell中也支持break跳出循环, continue跳出本次循环.用法与C, Java中相同 函数 要定义一个函数, 可以使用下面两种形式:


function funcname()
{
	do something
	}
复制代码

或者


funcname ()
{
	do something
	}
复制代码

看个例子


add()
{
	let "sum=$1+$2"
	return $sum
	}
add $1 $2
echo "sum=$?"
复制代码

输入 输出 其中, $?在shell中保存的是上一条命令的返回值 NOTE: 函数必须先定义后使用 如果在函数中使用exit会退出脚本, 如果想退回到原本函数调用的地方, 则可使用return 向脚本传递参数 先shell脚本传递参数, 非常简单, 只需要在你执行命令的后面跟上即可, 看个例子:


echo "$# parameters";
echo "$@";
echo "$0"
echo "$1"
复制代码

输入: 输出:

	

2 parameters
11 22
test.sh
11
复制代码

解释: $@代表所有参数的内容, $#代表所有参数的个数, $0代表脚本的名称, $1代表第一个参数的值. 后记 之所以要写这篇博客, 有以下几个原因: 想总结一下shell编程中的关键知识点, 方便日后查看. 想通过shell优化一下我的hexo写作及博客管理流程, 目前相关脚本已完成, 待我下一篇博客分享给大家, 如果你也是在用Hexo写博客, 相信对你会很有用, 尽请期待! 可以看的出这里总结的都是最关键的知识点, 还有很多这里并没有说. 是因为我觉得刚开始学习一个东西没必要太计较一些细节/琐碎的东西, 掌握好大致知识框架, 然后在大家编写具体的脚本时, 遇到具体问题, 再去google寻找即可. 参考 Shell脚本编程30分钟入门 Linux Shell编程从入门到精通
作者:CoderGhui
链接:https://juejin.cn/post/6844903437704904711
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值