Shell 编程入门

前言

无论是前端,后端还是移动端,大数据,AI还是运维,等等。作为一个高效的 Coder 都必须掌握 shell 编程。So,本文将告诉,入门 shell 其实很简单,抽点时间就能掌握的高回报率的小技能。

1. 基础知识

1.1 命令行

包行命令和参数的行称为命令行。语法格式如下:

command [arg1] [arg2] ... [argn] RETURN

其中 command 为命令的名称,arg1 ~ argn 为参数,RETURN 是终止命令行的按键。命令行语法中的方括号表明被括起来的参数为可选项。并不是所有命令都需要参数。选项是一种特殊类型的参数,其前面通常是一个或两个连字符(或称短线,负号:“-”)。多数实用程序的选项前面需要带一个连字符,而 GNU 程序的选项前面通常带有两个连字符。

1.2 shell

本质上,shell 只是执行命令的宏处理器(术语宏处理器是指扩展文本和符号以创建更大表达式的功能)。它既是命令解释器又是编程语言。作为命令解释器,shell 为丰富的 gnu 实用程序集提供用户接口;作为编程语言,允许组合这些实用程序,放在一个脚本文件中(通常后缀为 .sh 也可以不带后缀),构成新的命令,这些新命令具有与 /bin 等目录中的系统命令的具有相同可执行特性,允许用户或搭建立自定义环境以自动化其常见任务,来提高日常开发和运维效率。

shell 的实现有很多种,最常用的是 Bash (Bourne-Again Shell 的缩写),它是 GUN 操作系统的 shell 的解释器,也是本文使用的 shell。

2. test 内置命令

下文需要介绍的条件结构构循环结构,都需要用到 test 内置命令。正确掌握 test 的使用,是应用下文知识的前提。因此,放到前面先介绍。

2.1 格式

test 作为 shell 内置命令,它比较特殊,有两种等效写法:

2.1.1 test 命令方式

test -<opt> args

反逻辑:

test ! -<opt> args

2.1.2 中括号方式

比较推荐的使用方式,下文条件和循环结构都采用这种方式。

!!!注意: 中括号两边(与选项和参数之间)要有空格

[ -<opt> args ]

反逻辑:

[ ! -<opt> args ]

2.1.3 示例:判断文件是否存在

test 命令方式:

# 先在当前目录创建一个文件,用于测试
echo "" > file.txt

# 存在则执行后面 echo 命令
test -f file.txt && echo 'file.txt exist!'

# 不存在则执行后面 echo 命令
test ! -f file.txt && echo 'file.txt exist!'

中括号方式:

[ -f file.txt ] && echo 'file.txt exist!'

[ ! -f file.txt ] && echo 'file.txt exist!'

&& 用于连接多个 shell 命令,只有当前面的命令执行成功,才会执行后面的命令。作用类似 if 。

2.2 其他检查文件的选项

  • -e : 检查文件或目录是否存在
  • -d : 检查目录是否存在
  • -f : 检查文件是否存在
  • -s : 检查文件是否存在,以及该文件是否大于0字节
  • -r : 检查文件是否存在,以及该文件是否可读
  • -w : 检查文件是否存在,以及该文件是否可写
  • -x : 检查文件是否存在,以及该文件是否可执行

2.3 数值比较

上一小节列出的选项是检查文件是否存在,只能接受 1 个输入参数。当比较两个数值的关系时,需要用到数值比较选项。

  • -eq : 等于
  • -ne : 不等于
  • -gt : 大于
  • -ge : 大于等于
  • -lt : 小于
  • -le : 小于等于

示例:

a=1; [ $a -eq 1 ] && echo 'a is equal to 1'
a=2; [ $a -gt 1 ] && echo 'a is greater than 1'
a=1; [ $a -lt 2 ] && echo 'a is less than 2'

2.4 字符串比较

字符串比较使用和数值比较不一样的选项,并且只有两种关系:等于和不等于。

  • = : 等于
  • != : 不等于

示例:

a=hello; [ $a = hello ] && echo 'a is equal to hello'
a='hello'; [ $a != 'world' ] && echo 'a is not equal to world'

需要注意的是当将包含空格的字符串赋值给变量使用时,应该使用如下比较方式。

使用双引号将变量包裹起来:

a='hello world'; [ "$a" = 'hello world' ] && echo 'a is equal to "hello world"'

或者使用双中括号 [[ … ]] :

a='hello world'; [[ $a = 'hello world' ]] && echo 'a is equal to "hello world"'

3. 条件结构

3.1 if … then

3.1.1 语法格式

if test-command
    then
        commands
fi

或(更常用的写法):

if test-command; then
    commands
fi

单行写法(将换行符号换成分号):

if test-command; then commands; fi

3.1.2 示例

保存到 if_test.sh 文件中。

a=1
if [ $a -eq 1 ]; then
    echo 'a is equal to 1'
fi

或(可直接在命令行输入):

a=1; if [ $a -eq 1 ]; then echo 'a is equal to 1'; fi

3.2 if … then … else

3.2.1 语法格式

if test-command; then
        commands
    else
        commands
fi

3.2.2 示例

将脚本保存到 if_else_test.sh 文件中。

if [[ $1 = 'hello world' ]]; then
    echo "parameter 1 is equal to hello world"
else
    echo "parameter 1 is not equal to hello world"
fi

命令行运行:

$ sh if_else_test.sh 'hello world'
parameter 1 is equal to hello world
$ sh if_else_test.sh 'hello world2'
parameter 1 is not equal to hello world

3.3 if … then … elif

3.3.1 语法格式

if test-command; then
    commands
elif test-command; then
    commands
...
else
    commands
fi

3.3.2 示例

将脚本保存到 if_elif_test.sh 文件中。

if [ $# -eq 0 ]; then
    echo 'no parametes'
elif [ $# -eq 1 ]; then
    echo 'only one parameter'
else
    echo 'many parameters'
fi

命令行运行:

$ sh if_elif_test.sh
no parametes
$ sh if_elif_test.sh 1
only one parameter
$ sh if_elif_test.sh 1 2
many parameters

4. 循环结构

4.1 for … in

4.1.1 语法格式

for loop-index in argument-list; do
    commands
done

4.1.2 示例

将脚本保存到 for_in_test.sh 文件中。

for i in 1 2 3; do
    echo $i
done

for f in *.sh; do
    echo $f
done

命令行运行:

$ sh for_in_test.sh
1
2
3
for_in_test.sh
if_elif_test.sh
if_else_test.sh
if_test.sh

4.2 while

4.2.1 语法格式

while test-command; do
    commands
done

4.1.2 示例

将脚本保存到 while_test.sh 文件中。

i=0
while [ $i -lt 3 ]; do
    echo $i
    ((i += 1))
done

命令行运行:

$ sh while_test.sh
0
1
2

5. 变量

shell 中使用变量比较简单,前文也已经多处使用到变量。

5.1 创建

使用 ‘=’ 通过给标识符赋值即可创建变量。需要注意的是等号 ‘=’ 两边不能有空格。

a=1
b='hello'

5.2 访问

访问或读取变量,需要在变量标识符前加 ‘$’。

echo $a
echo $b

6. 函数

函数是稍后执行(区别于马上执行)的一系列命令的集合。

6.1 语法格式

其中关键字 function 可要可不要。当加上 function 时,函数名后面的圆括号可以省略。和其他语言不同的是,shell 函数不能接受参数,调用时也不能使用圆括号。

function-name() {
    commands
}
function function-name {
    commands
}

6.2 示例

将以下脚本保存到文件 func_test.sh 中。

f=$1

sec_rm_file() {
    if [ -f $f ]; then
        echo "remove file $f ..."
        rm -f $f
    else
        echo "$f not existed."
    fi
}

function tips {
    echo 'need 1 argument at least'
}

if [ $# -ne 0 ]; then
    sec_rm_file
else
    tips
fi

命令行运行:

$ sh func_test.sh file.txt
remove file file.txt ...
$ sh func_test.sh file.txt
file.txt not existed.

参考

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券