前言
Shell是一种让使用者可以和作业系统kernal(用来控制CPU、记忆体、硬碟等硬体)互动沟通的桥梁。Shell Script主要是使用在Linux和MacOS等Unix-like作业系统的自动化操作指令的程式语言。其透过Unix shell命令列直译器来执行(我们这边主要使用bash shell,其他的Unix shell观念大致类似),使用方式有点类似直译式程式语言(不用编译直接执行)。在Windows系列家族也有类似的使用方式:Batch file。
一般情况Shell Script常用于系统管理、自动化操作档案、自动化重复的指令码、分析log等文件档案、列印呈现我们想要的资料等,透过程式语言的使用来减少重复琐碎的工作,所以若能妥善使用将提升不少开发者和软体工程师的日常工作效率。接着我们将透过日常生活常用的使用情境,带领读者们进入入门Shell Script(读者需要具备基本Linux指令码的基本观念,若你需要复习常见Linux指令可以参考 Linux Command命令列指令与基本操作入门教学) 。
Shell Script 初体验
在撰写Shell Script之前我们先来了解Shell Script撰写的流程和架构。一般我们会使用 .sh
副档名来命名Shell Script档案。然后将该档案设定为可执行:
1
|
chmod +x demo.sh
|
可以透过检视档案详细资料观看是否已有 +x
的执行权限:
1 2 3 |
ls -l demo.sh # -rwxr-xr-x 1 user staff 106 Nov 16 10:41 demo.sh |
执行Shell Script 档案:
1
|
./demo.sh
|
接着,我们先利用一个简单的范例:将目前执行process 的PID 依照数字大小排序,取出前10 名,来了解撰写Shell Script 的基本架构。
1 2 3 4 5 6 7 |
#宣告使用/bin/bash #!/bin/bash echo "===将目前执行process的PID依照数字大小排序,取出前10名=== " # ps为列出process相关资讯,透过| pipe管线传递资料。awk可以根据pattern进行资料处理(这边印出第一栏PID)而sort是进行排序,其排序时,预设都是把资料当作字串来排序,若想让资料根据实际数值的大小来排序,可以加上-n参数。-r则是由大到小排序,预设是由小到大 ps | awk '{print $1}' | sort -rn | head -10 |
执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 |
$ ./demo.sh ===将目前执行process的PID依照数字大小排序,取出前10名=== 83784 83783 75956 75955 75954 75952 74069 74068 73543 37621 |
恭喜你,你已经完成了第一个Shell Script 程式了!
变数
一般来说程式语言中变数是用来暂存接下来会使用到的资料或是储存指到物件的参考位置。在Shell Script 可以使用以下三种方式来宣告变数并给定值:
1 2 3 4 5 6 |
#!/bin/bash variable1=value #若是值内有空白则需要使用''或""包裹起来 variable2='value 2' variable3="value 3" |
注解使用#,因为没有多行注解,所以需要使用多单行注解达到
使用变数方式为 ${變數名稱}
,花括号主要是辅助了解变数的范围:
1 2 3 4 5 |
#!/bin/bash pathName=demo.sh # echo是列印值,印出变数pathName内容demo.sh echo ${pathName} |
更新变数直接重新assign 值即可:
1 2 3 4 5 6 7 8 9 |
#!/bin/bash pathName=demo1.sh #印出demo1.sh echo ${pathName} pathName=demo2.sh #印出demo2.sh echo ${pathName} |
删除变数使用 unset
:
1 2 3 4 5 6 7 8 |
#!/bin/bash pathName=demo.sh #印出demo.sh echo ${pathName} unset pathName #空值 echo ${pathName} |
注意系统环境变数为全域变数、区域变数则为Shell Script 内部程式使用,不能跨档案使用。
运算式
运算式是当运算子和运算元计算结果回传后赋值给变数。在Bash Shell 中内建原生不支援运算式,但我们可以使用expr、awk 等指令来支援实现运算式。
算式
我们可以使用四则运算来赋值:
1 2 3 4 5 6 |
#!/bin/bash result=`expr 10 + 2` # 12 echo "Result: $result" |
条件判断
在Shell Script中同样可以使用if..else条件判断,特别注意的是在Shell Script中使用 fi
为结尾(为 if
的倒写法,同样的接下来讨论的 case
也有类似用法),代表条件判断结束。==
为等于,!=
为不等于运算子。
if
1 2 3 4 5 6 7 8 9 10 11 12 |
#!/bin/sh x=20 y=30 if [ $x == $y ]; then echo "value x is equal to value y" fi if [ $x != $y ]; then echo "value x is not equal to value y" fi |
if else
在Shell Script可以使用 -gt
(greater than缩写)和 -lt
(less than缩写)代表大於
和小於
,而 -ge
(greater equal缩写)和 -le
(less equal缩写)则是大於等於
和小於等於
的运算子符号。
记得比较条件需要放在[] 中,前后要留空白
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#!/bin/bash if [ $x -gt $y ]; then echo "value x is greater than value y" else echo "value x is not greater than value y" fi if [ $x -lt $y ]; then echo "value x is not less than value y" else echo "value x is not less than value y" fi if [ $x -ge $y ]; then echo "value x is greater or equal than value y" else echo "value x is not greater than value y" fi if [ $x -le $y ]; then echo "value x is not less or equal than value y" else echo "value x is not less or equal than value y" fi |
if elif else
若有多个条件需要判断,可以使用 if elif else
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#!/bin/bash value1=20 value2=30 value3=30 if [ $value1 -gt $value2 ]; then echo "value1 is greater than value2" elif [ $value1 == $value3 ]; then echo "value1 is equal to value3" else echo "other result" fi |
case … esac
若要使用类似一般程式语言的 switch
来处理多种条件判断时,可以使用 case
来进行判断:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#!/bin/bash language='Java' case $language in Java*) echo "是Java!" ;; Python*) echo "是Python!" ;; C*) echo "是C!" ;; *) echo "没match到!" esac |
回圈
当我们需要重复某些琐碎的任务或是迭代取得资料就需要回圈来支援。此时可以使用 for
、while
和 until
回圈进行迭代。
for
Shell Script的 for
使用方法和一般程式语言类似,同样可以针对条件使用 break
、continue
来跳出或是跳过回圈。
1 2 3 4 5 |
#!/bin/bash for loop in 1 2 3; do echo "number: $loop" done |
while
若是需要设定一个条件直到该条件为止,可以使用 while
,但要注意避免无限回圈状况:
1 2 3 4 5 6 7 |
#!/bin/bash counter=0 while [ $counter -le 5 ]; do counter='expr $counter+1' echo $counter done |
until
直到某个条件结束可以使用 until
来进行:
1 2 3 4 5 6 7 8 |
#!/bin/bash #从0印出数字直到10 counter=0 until [ $counter -gt 10 ]; do echo $counter counter=`expr $counter + 1` done |
函式
随着我们的程式越来越大,我们需要透过模组化或是将重复使用的程式码改成函式。函式基本架构如下:
- 函式名称(
function
关键字为选择性) - 是否有传入参数
- 函式内操作
- 是否有回传值
1 2 3 4 |
function function_name () { #做一些事情 [回传值] } |
函式范例:
1 2 3 4 5 6 7 8 |
#!/bin/bash function echoHello() { # hello world, rock!! echo "${0} hello ${1}, ${2}!!" } echoHello 'world' 'rock' |
以上我们可以看到使用 ""
双引号把字串和变数取出来印出(你可以试试看使用单引号会发生什么事情),与一般程式语言比较不同的是其函式呼叫不需要有小括号传入参数,直接以空白当作参数传递的格式。注意参数从1开始,${0}
为档名。
特殊变数
在Shell Script 档案和函式往往需要透过传入参数来设定执行程式的内容。在Shell Script 支援许多好用的特殊变数,可以方便我们透过使用变数方式来设置程式执行的流程。
指令 | 描述 | 注解 |
---|---|---|
$0 | 目前的档案档名 | |
$n | n 从1 开始,代表第几个参数 | |
$# | 传递到程式或函式目前有几个参数 | |
$* | 传递到程式或函式所有参数 | |
$@ | 类似$* 但是在被双引号包含时有些许不同 | |
$? | 上一个指令退出状态或是函式的返回值 | |
$$ | 目前process PID |
透过执行 ./demo_special_var.sh var1 var2
:
1 2 3 4 5 6 7 8 9 |
#!/bin/bash echo "$0" echo "$1" echo "$#" echo "$*" echo "$@" echo "$?" echo "$$" |
印出结果:
1 2 3 4 5 6 7 |
./demo.sh var1 2 var1 var2 var1 var2 0 80417 |
总结
以上我们透过循序渐进入门了Shell Script并撰写了我们第一个Shell Script程式,并了解如何在Shell Script中使用变数、条件判断、回圈、函式以及特殊变数。Shell Script常用于系统管理、自动化操作档案、自动化重复的指令码、分析log等文件档案、列印呈现我们想要的资料等,透过程式语言的使用来减少重复琐碎的工作,快把Shell Script放入你的工具箱中吧!若能妥善使用将提升不少开发者和软体工程师的日常工作效率。
一、如果您发现本站侵害了相关版权,请附上本站侵权链接和您的版权证明一并发送至邮箱:yehes#qq.com(#替换为@)我们将会在五天内处理并断开该文章下载地址。
二、本站所有资源来自互联网整理收集,全部内容采用撰写共用版权协议,要求署名、非商业用途和相同方式共享,如转载请也遵循撰写共用协议。
三、根据署名-非商业性使用-相同方式共享 (by-nc-sa) 许可协议规定,只要他人在以原作品为基础创作的新作品上适用同一类型的许可协议,并且在新作品发布的显著位置,注明原作者的姓名、来源及其采用的知识共享协议,与该作品在本网站的原发地址建立链接,他人就可基于非商业目的对原作品重新编排、修改、节选或者本人的作品为基础进行创作和发布。
四、基于原作品创作的所有新作品都要适用同一类型的许可协议,因此适用该项协议, 对任何以他人原作为基础创作的作品自然同样都不得商业性用途。
五、根据二〇〇二年一月一日《计算机软件保护条例》规定:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可不经软件著作权人许可,无需向其支付报酬!
六、鉴此,也望大家按此说明转载和分享资源!本站提供的所有信息、教程、软件版权归原公司所有,仅供日常使用,不得用于任何商业用途,下载试用后请24小时内删除,因下载本站资源造成的损失,全部由使用者本人承担!