前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Shell 编程入门

Shell 编程入门

作者头像
我是一条小青蛇
发布2019-10-23 17:09:18
9290
发布2019-10-23 17:09:18
举报
文章被收录于专栏:青笔原创青笔原创

前言

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

1. 基础知识

1.1 命令行

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

代码语言:javascript
复制
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 命令方式
代码语言:javascript
复制
test -<opt> args

反逻辑:

代码语言:javascript
复制
test ! -<opt> args
2.1.2 中括号方式

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

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

代码语言:javascript
复制
[ -<opt> args ]

反逻辑:

代码语言:javascript
复制
[ ! -<opt> args ]
2.1.3 示例:判断文件是否存在

test 命令方式:

代码语言:javascript
复制
# 先在当前目录创建一个文件,用于测试
echo "" > file.txt

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

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

中括号方式:

代码语言:javascript
复制
[ -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 : 小于等于

示例:

代码语言:javascript
复制
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 字符串比较

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

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

示例:

代码语言:javascript
复制
a=hello; [ $a = hello ] && echo 'a is equal to hello'
a='hello'; [ $a != 'world' ] && echo 'a is not equal to world'

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

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

代码语言:javascript
复制
a='hello world'; [ "$a" = 'hello world' ] && echo 'a is equal to "hello world"'

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

代码语言:javascript
复制
a='hello world'; [[ $a = 'hello world' ]] && echo 'a is equal to "hello world"'

3. 条件结构

3.1 if … then

3.1.1 语法格式
代码语言:javascript
复制
if test-command
    then
        commands
fi

或(更常用的写法):

代码语言:javascript
复制
if test-command; then
    commands
fi

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

代码语言:javascript
复制
if test-command; then commands; fi
3.1.2 示例

保存到 if_test.sh 文件中。

代码语言:javascript
复制
a=1
if [ $a -eq 1 ]; then
    echo 'a is equal to 1'
fi

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

代码语言:javascript
复制
a=1; if [ $a -eq 1 ]; then echo 'a is equal to 1'; fi

3.2 if … then … else

3.2.1 语法格式
代码语言:javascript
复制
if test-command; then
        commands
    else
        commands
fi
3.2.2 示例

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

代码语言:javascript
复制
if [[ $1 = 'hello world' ]]; then
    echo "parameter 1 is equal to hello world"
else
    echo "parameter 1 is not equal to hello world"
fi

命令行运行:

代码语言:javascript
复制
$ 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 语法格式
代码语言:javascript
复制
if test-command; then
    commands
elif test-command; then
    commands
...
else
    commands
fi
3.3.2 示例

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

代码语言:javascript
复制
if [ $# -eq 0 ]; then
    echo 'no parametes'
elif [ $# -eq 1 ]; then
    echo 'only one parameter'
else
    echo 'many parameters'
fi

命令行运行:

代码语言:javascript
复制
$ 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 语法格式
代码语言:javascript
复制
for loop-index in argument-list; do
    commands
done
4.1.2 示例

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

代码语言:javascript
复制
for i in 1 2 3; do
    echo $i
done

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

命令行运行:

代码语言:javascript
复制
$ 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 语法格式
代码语言:javascript
复制
while test-command; do
    commands
done
4.1.2 示例

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

代码语言:javascript
复制
i=0
while [ $i -lt 3 ]; do
    echo $i
    ((i += 1))
done

命令行运行:

代码语言:javascript
复制
$ sh while_test.sh
0
1
2

5. 变量

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

5.1 创建

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

代码语言:javascript
复制
a=1
b='hello'

5.2 访问

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

代码语言:javascript
复制
echo $a
echo $b

6. 函数

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

6.1 语法格式

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

代码语言:javascript
复制
function-name() {
    commands
}
代码语言:javascript
复制
function function-name {
    commands
}

6.2 示例

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

代码语言:javascript
复制
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

命令行运行:

代码语言:javascript
复制
$ sh func_test.sh file.txt
remove file file.txt ...
$ sh func_test.sh file.txt
file.txt not existed.

参考

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-302,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 1. 基础知识
    • 1.1 命令行
      • 1.2 shell
      • 2. test 内置命令
        • 2.1 格式
          • 2.1.1 test 命令方式
          • 2.1.2 中括号方式
          • 2.1.3 示例:判断文件是否存在
        • 2.2 其他检查文件的选项
          • 2.3 数值比较
            • 2.4 字符串比较
            • 3. 条件结构
              • 3.1 if … then
                • 3.1.1 语法格式
                • 3.1.2 示例
              • 3.2 if … then … else
                • 3.2.1 语法格式
                • 3.2.2 示例
              • 3.3 if … then … elif
                • 3.3.1 语法格式
                • 3.3.2 示例
            • 4. 循环结构
              • 4.1 for … in
                • 4.1.1 语法格式
                • 4.1.2 示例
              • 4.2 while
                • 4.2.1 语法格式
                • 4.1.2 示例
            • 5. 变量
              • 5.1 创建
                • 5.2 访问
                • 6. 函数
                  • 6.1 语法格式
                    • 6.2 示例
                    • 参考
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档