Shell脚本初探

410 阅读2分钟

之前在写控制台的时候,使用到了项目里面的shell脚本,然后发现我们开发过程中可以使用shell脚本去方便我们的一些业务场景,提高我们的工作效率,减少一些重复性的操作,特写一篇文章分享自己对于shell脚本的一些认识和使用

Shell 和 Shell脚本

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。

我理解它们之间的关系是这样的

基本结构

一个shel脚本的最基本的结构如下所示

#!/bin/bash
echo "hello world"
exit 0

语句

  • #!/bin/bash 声明shell脚本使用的shell的名称

  • exit 0 是用来返回脚本执行结果的,类似c/c++会在main函数里面用return 0作为返回的结果,在脚本执行完成之后可以用通过 echo $? 返回脚本执行的结果

执行脚本

shell脚本的执行有两种方法,一种是作为可执行的程序执行

chmod +x ./shanshan.sh // 使脚本具有执行权限
./shanshan.sh

其中chmod是控制用户对文件的权限的命令,+x是指赋予文件执行的权限

另外一种是使用shell的解释器,将脚本作为参数执行

/bin/bash ./shanshan.sh
/bin/sh ./shanshan.sh

shell脚本编程的基本语法

变量

常见的变量有两种,一种是shel脚本的定义的变量,如下

#!/bin/bash
name="shanshan"
echo ${name}
exit 0

其中变量赋值时不可以有空格,可通过 $ 引用定义过的变量

另一种是调用脚本传入的参数变量,如下

#!/bin/bash
echo "传入的参数的个数:$#"
echo "传入的参数的是:$@"
echo "执行的文件名:$0"
echo "第一个参数名:$1"
echo "第二个参数名:$2"
exit 0

执行 ./shanshan.sh 1 2 3

可输出如下

还有一些特殊字符可用来处理参数,就不一一举栗子~

数组

shell脚本数组用括号来表示,元素用"空格"符号分割开,语法格式如下

arr=(value0 value1 value2)
  • ${arr[index]} 可用来获取数组中的元素

  • ${arr[*]}${arr[@]} 可用来获取数组中所有的元素

  • ${#arr[*]}${#arr[@]}可用来获取数组的长度

条件语句

  • if 的语法格式如下
if [ $1 == 1 ];
then
    echo "fisrt param is one"
elif [ $1 == 2 ];
then
    echo "fisrt param is two"
else
    echo "other"
fi

需要注意的是它的格式,可见 if 和判断条件之间都存在空格,在[]中进行一些条件的判断,以 fi 作为这条语句的结束

  • switch 的语法格式如下
case $1 in
1)
    echo "fisrt param is one";;
2)
    echo "fisrt param is two";;
*)
    echo "other";;
esac

其中的*)表示的是他可以匹配任意值,;;表示break,执行结束

  • 循环

其中常见的两种循环有while和for循环

while循环的语法格式如下

num=$1
while [ $num != 3 ]
do
    echo $num
    ((num=num+1))
done
echo $num

for循环的语法格式如下

for (( i=1; i<3; i++))
do
    echo $i
done

函数

function print() {
    echo "parame 1 is $1 2 is $2"
}
print a b

使用函数时在函数名后用空格分开传入参数

日常开发中常见的几种业务的场景

介绍完了上面一些基本的语法,其实就可以写一些基本的脚本了,也可以去读懂一些脚本的语句了,其实我们项目里面就已经有很多的这个脚本了,不知道大家注意没有,我们在一些业务场景上面还是会比较频繁的需要去使用到它们的

使用shell脚本将打包的文件部署到服务器上

在我们没有使用或者搭建Jenkins去部署某一个环境的时候,我们可以自己手动使用这个命令去将我们打包出来的dist包上传到该环境的服务器上面

#!/bin/bash
source="./dist/console"
target="/opt/dtstack/DTConsole/ConsoleFront"
server="172.16.100.168"

echo "Uploading $source to $server:$target"

### 上传文件到指定服务器
scp -P 22 -r $source root@$server:$target

echo "Upload over."

使用shell脚本推包

每次我们往私有仓库推包也是在使用一样的命令,并且registry的地址非常长,可以使用shell脚本将这个命令简化~

#!/bin/bash
registry="http://registry.npm.dtstack.com/"
package=""

while [[ $# > 0 ]];
do
    case $1 in
    -D)
        package=$2;
        shift;;
    *)
        echo "Unknown parameter passed: $1";
        exit 1;;
    esac;
    shift;
done

npm set registry $registry

if [ ! -z $package ];
then
    echo "package is ${package}"
    npm unpublish $package --registry $registry
    echo "Unpublish over."
else
    npm publish --registry $registry
    echo "Publish over."
fi

可执行./publish.sh推送当前版本的私有仓库的包, ./publish.sh -D dt-common@version删除对应的私有仓库的包

使用shell脚本打tag

在很久之前,我们部门还是需要我们开发自己去基于这个release的分支去执行npm run release打一个tag,其实这个就是去执行了我们项目下的这个shell脚本,其中这个脚本执行了如下的一些语句

#!/bin/bash

while [[ $# > 0 ]];
do
    case $1 in
    -r|--release)
        release="$2";
        shift;;
    -b|--branch)
        branch="$2";
        shift;;
    *)
        echo "Unknown parameter passed: $1";
        exit 1;;
    esac;
    shift;
done

# Default as minor, the argument major, minor or patch: 
if [ -z $release ];
then
    release="minor";
fi

# Default release branch is master 
if [ -z $branch ];
then
    branch="master"; 
fi;


echo "Branch is $branch"
echo "Release as $release"

# Tag prefix
prefix="DTinsight_v"
git pull origin $branch
echo "Current pull origin $branch."

# Auto generate version number and tag
standard-version -r $release --tag-prefix $prefix --infile CHANGELOG.md

git push --follow-tags origin $branch

echo "Release finished."

总结

在我们日常的开发中还是有比较多的地方使用到了shell脚本的,给我们带来了便利,避免一些重复性的操作,了解一些shell脚本的基本的语法对于我们前端开发来说也是很有帮助的,以上是我对于shel脚本的一些浅薄的认识,如果有不对之处欢迎指正~