【问题标题】:How to syntax check a shell script before sourcing it?如何在采购之前对 shell 脚本进行语法检查?
【发布时间】:2023-12-27 18:16:01
【问题描述】:

我想运行这个命令source .env(采购一个 .env 文件),如果.env 文件在采购时有一些错误。我想在错误输出“嘿,你的 .env 中有错误”之前显示一条消息,否则如果没有错误,我不想显示任何内容。

这是一个需要编辑的代码示例:

#!/bin/zsh

env_auto_sourcing() {
  if [[ -f .env ]]; then    

    OUTPUT="$(source .env &> /dev/null)" 
    echo "${OUTPUT}"

    if [ -n "$OUTPUT" ]; then
        echo "Hey you got errors in your .env"
        echo "$OUTPUT"

  fi
}

【问题讨论】:

  • shellcheck.net也是可下载/可安装的软件,比bash -n更全面。

标签: bash shell


【解决方案1】:

为什么不直接使用命令source中的退出代码?

您不必为此使用bash -n,因为...

假设您的 .env 文件包含这 2 行无效行:

dsadsd
sdss

如果您使用上面的示例运行当前接受的代码:

if errs=$(bash -n .env 2>&1);

上述情况将无法停止文件的采购。

所以,你可以使用source 命令返回码来处理这一切:

#!/bin/bash
# This doesn't actually source it. It just test if source is working
errs=$(source ".env" 2>&1 >/dev/null)
# get the return code
retval=$?
#echo "${retval}"
if [ ${retval} = 0 ]; then
  # Do another check for any syntax error
  if [ -n "${errs}" ]; then
    echo "The source file returns 0 but you got syntax errors: "
    echo "Error details:"
    printf "%s\n" "${errs}"
    exit 1
  else
    # Success here. we know that this command works without error so we source it
    echo "The source file returns 0 and no syntax errors: "
    source ".env"
  fi
else
  echo "The source command returns an error code ${retval}: "
  echo "Error details:"
  printf "%s\n" "${errs}"
  exit 1
fi

这种方法的最佳之处在于,它还将检查bash 语法和source 语法:

现在您可以在 env 文件中测试这些数据:

-
~
@
~<
>

【讨论】:

    【解决方案2】:

    您可以使用bash -nzsh 也有一个-n 选项)在获取脚本之前对其进行语法检查:

     env_auto_sourcing() {
      if [[ -f .env ]]; then
        if errs=$(bash -n .env 2>&1); 
            then source .env; 
        else 
            printf '%s\n' "Hey you got errors" "$errs"; 
        fi
      fi
     }
    

    将语法检查错误存储在文件中比您在代码中使用的 subshel​​l 方法更简洁。

    bash -n 有一些陷阱,如下所示:

    【讨论】:

    • 我会考虑一个命令替换,即。 if errs=$(bash -n .env 2&gt;&amp;1); then source .env; else printf '%s\n' "Hey you got errors" "$errs"; fi,避开临时文件。