执行shell脚本的多个方式

如何执行shell脚本

问题描述

  • 接着上一篇继续分析关于脚本部分的
  • 在该job中让其执行以下shell
#注意$script指的是一段脚本
SHELL_SCRIPT=test.sh
echo $script > $SHELL_SCRIPT
docker copy . $container:/var/app
docker exec -i $container sh -c "cd /var/app && chmod +x   $SHELL_SCRIPT && sh $SHELL_SCRIPT" 
#$script如下
#!/bin/bash
master_branch=$(git branch | grep master)
test_branch=$(git branch | grep test)

if [[ ! -n $master_branch -o ! -n $test_branch ]]; then
    echo "分支不存在!";
    exit 1;
fi

 echo "分支存在!";
  • 发现脚本报错:'[['出错
  • sh 改成bash chmod +x $SHELL_SCRIPT && bash $SHELL_SCRIPT发现不报错,但是出现git not found
  • 将当前的conatiner从afaren/alpine-gradle 改成 node发现git不报错了但是执行结果却是分支存在
  • 使用conatiner是node发现并提交一个包含所有分支的仓库却发现被echo出分支不存在

问题分析

  • Q1: 如何执行一个script文件?

  • A1: 执行方式可以大致分成两种:

    • 第一种:形如sh script.sh 或者 bash script.sh 或者 source script.sh
      • 这种方式是使用一个命令运行一个shell脚本,因此这个脚本不需要具有可执行权限
      • 但是需要保证当前的shell中有sh 或者 bash 或者source指令否则会报错
      • 在这种情况下,对于script文件中可以不用书写第一行#!/bin/**,因为脚本一定会使用指令中确定的shell执行
      • 此时外部的指令(sh bash)的优先级高于文件中的#!/bin/bash,换句话说当文件中定义的shell执行器类型不同于指令中的shell执行器,该shell文件还是会被使用指令中的执行器执行
      • 指令中三种不同的shell区别
        - sh:
        - 包含命令少,因此可能会导致脚本中有些指令not found,并且在执行脚本文件的时候。
        - 会开启一个新的子shell执行该脚本
        - bash:
        - 包含命令多
        - 会开启一个新的子shell执行该脚本
        - source
        - 会在当前的shell执行该脚本
    • 第二种:形如./script.sh
      • 要求该脚本一定是具备可执行权限的
      • 并且脚本的执行器由脚本第一行的#!定义
      • 如果没有在脚本中定义第一行#!,那么就会使用当前shell中的默认执行器执行脚本文件
    • 也就是说,对于本例子中,根本没有必要在docker exec -i $container sh -c "cd /var/app && chmod +x $SHELL_SCRIPT && sh $SHELL_SCRIPT"我们希望使用sh执行脚本。
  • Q2:那么使用sh执行脚本为什么会报错?使用bash就不会?

  • A2:因为

    • bash和sh区别之一:bash的命令多于sh所以,有些命令bash可以执行,但是sh不可以,那么如何分辨呢?
      • 可以使用:sh -c "type **"或者bash -c "type **"如果返回值是**: not found说明sh或者bash中没有这个指令,** is a shell keyword说明有
    • bash和sh还有一点区别:sh执行的时候某些指令如果file not found会在这句出现的时候停止,但是bash会继续执行下去(不是说sh是bash的严格模式)
  • Q3:为什么git not found?

  • A3:我们使用的docker镜像主要分成两大类:

    • 一种是正常的镜像
    • 一种是alpine镜像:比较小,所有包含的功能少,最主要的体现就是没有bash 和git两种指令
  • Q4:既然shell脚本可以正常执行了,为什么无法echo出“分支不存在”这样正确的结果呢?

  • A4:首先看一下if判断语句,先保证两个变量都可以拿到想拿到的值,看看变量定义,使用$()包住指令拿到指令的标准输出,没问题。然后查看判断变量为空的操作是否正确。判断变量是否为空的操作有三种做法,我的判断变量是否为空的做法一定是错的:

    • 方法一:if [ ! -n "$test_branch" ]使用-n但是请注意,变量一定要使用""包裹住,将变量的值先变成一个字符串。
    • 方法二:if [ ! $test_branch ]
    • 方法三:if [ "$test_branch" = "" ]

你可能感兴趣的:(执行shell脚本的多个方式)