Shell is a programming language, it also has variables/functions/operators/if statements/loop control/… like other programming languages like: C, Java, Python, etc. But before we start, I want to clarify Shell language and Shell The relationship between.
Shell and Shell Language
The above said that Shell is a programming language, but you may have heard of it: sh/bash/csh/zsh/… They are also called Shell, in fact, the Shell mentioned here is an application, which is responsible for interpreting and executing what you write. Shell script , Mac comes with sh/bash/csh/zsh/tcsh/ksh by default , you can check cat /etc/shells
that the usage of different shells is basically the same, but some shells provide some new features, for example, what I am using now is zsh, for more zsh content, you can read this article.
first shell script
#! /bin/sh echo "hello shell!"
According to international practice, it starts with printing a hello shell! in the terminal. The #! on the first line is a convention mark, which tells the script what interpreter this script needs to execute. The echo command on the second line is responsible for sending the message to the screen. Output a sentence.
how to run
There are 3 ways to run a shell program:
- chmod +x makes the file executable and runs directly
- Call the interpreter directly, passing the script file as an argument (for example
bash hi.sh
) - Execute the file using source (also available instead of .)
通常情况下, 最方便的方式就是方式1, 通过方式1执行你需要在脚本第一行写好这段脚本由哪个解释器来解释, 而通过方式2来执行则没有这个限制, 写了也没用.
除此之外方式1与方式2执行命令就没有区别了, 但方式3执行的方式与前两种都不同:
使用source执行shell脚本时, 不会创建子进程, 而是在父进程中直接执行!
这里不作更多解释, 感兴趣的同学可以去参考Linux Shell编程从入门到精通这本书的第一章的相关部分.
变量
和其它语言一样Shell中也有变量, 而且更简单, 但有一些比较特殊的地方.
- Shell中的变量只有字符串这一种类型
- Shell中变量名与变量值没有长度限制
- Shell的变量也允许比较操作和整数操作, 只要变量中的字符串为数字
定义变量
variable_name=ghui
需要注意: = 两边不能加空格, 当赋值语句包含空格时请加引号(单引号/双引号均可)比如:
variable_name="ghui's blog"
Shell中的变量可以分为两种类型:
- 局部变量 (定义变量时在前面加
local
修饰符) - 全局变量 (定义变量时不加任何修饰符)
与其它语言一样局部变量的可见范围是代码块或函数内, 全局变量在全局范围内可见.看个简单的例子:
#! /bin/sh 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} #{} 为了帮助解释器识别变量边界, 非必须
在使用变量时还有一个地方需要注意, 请看下面的例子:
#! /bin/sh str='abc' echo "1 print $str" echo '2 print $str'
输出:
1 print abc 2 print $str
即:
被双引号括起来的变量会发生变量替换, 单引号不会
注释
Shell中注释使用#, 而且它不支持多行注释.
常用的字符串操作
字符串拼接
name="shell" sayHi="hello, "$name" !" sayHi2="hello, ${name} !" echo $sayHi $sayHi2
注意: 上面说的单双引号引起的变量替换问题
获得字符串长度
string="abcd" echo ${#string} #输出:4
截取字符串
str="hello shell" echo ${str:2} #输出: llo shell echo ${string:1:3} #输出:ell
更多关于字符串的操作可以看这个
if/else流程控制
基本语法结构:
if condition then do something elif condition then do something elif condition then do something else do something fi
其中, elif语句和else语句非必须的.看个例子:
#! /bin/sh a=1 if [ $1=$a ] then echo "you input 1" elif [ $1=2 ] then echo "you input 2" else #do nothing 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
看个例子:
#! /bin/sh 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
看个例子:
#! /bin/sh i=0 while ((i<5)); do ((i++)) echo "i=$i" done
输出:
i=1 i=2 i=3 i=4 i=5
NOTE: 你可能需要去了解一下(())
的用法
until循环
基本结构
until condition do do something... done
看个例子:
#! /bin/sh i=5 until ((i==0)) do ((i--)) echo "i=$i" done
输出:
i=4 i=3 i=2 i=1 i=0
跳出循环
shell中也支持break
跳出循环, continue
跳出本次循环.用法与C, Java中相同
函数
要定义一个函数, 可以使用下面两种形式:
function funcname() { do something }
或者
funcname () { do something }
看个例子
#! /bin/sh # ad.sh 计算sum add() { let "sum=$1+$2" return $sum } add $1 $2 echo "sum=$?"
输入
ad 1 2
输出
sum=3
其中, $?
在shell中保存的是上一条命令的返回值
NOTE:
- 函数必须先定义后使用
- 如果在函数中使用
exit
会退出脚本, 如果想退回到原本函数调用的地方, 则可使用return
向脚本传递参数
先shell脚本传递参数, 非常简单, 只需要在你执行命令的后面跟上即可, 看个例子:
#! /bin/sh # test.sh echo "$# parameters"; echo "$@"; echo "$0" echo "$1"
输入:
test.sh 11 22
输出:
2 parameters 11 22 test.sh 11
http://www.techug.com/linux-shell-bash-zsh