首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当源文件表示脚本顶部的变量时,为什么外壳检查失败?

当源文件表示脚本顶部的变量时,为什么外壳检查失败?
EN

Stack Overflow用户
提问于 2019-10-28 08:36:33
回答 3查看 17.8K关注 0票数 23

Ubuntu 16.04

Bash 4.3.48

当源文件表示脚本顶部的shellcheck时,为什么$variables会失败?

下面是一个简单的脚本:

代码语言:javascript
复制
#!/bin/bash

. .sourcefile

echo "Today is ${day}."

这是我的源文件:

代码语言:javascript
复制
day="Monday"

以下是shellcheck的答复:

代码语言:javascript
复制
me@myserver:~$ shellcheck start.sh

In start.sh line 5:
echo "Today is ${day}."
               ^-- SC2154: day is referenced but not assigned.

有什么方法让shellcheck知道源文件中有$variables吗?

这里是我在Ubuntu16.04上所做的工作

@Dash-o解释如下:

首先,在源文件声明前面的行中添加源代码指令,如下所示:

# shellcheck source=/path/to/sourcefile

代码语言:javascript
复制
#!/bin/bash

# shellcheck source=./.sourcefile
. .sourcefile

echo "Today is ${day}."

接下来,在脚本之前使用-x选项执行-x如下:

shellcheck -x start.sh

代码语言:javascript
复制
me@myserver:~$ shellcheck -x start.sh

当使用-x选项时,shellcheck将遵循在源指令下面声明的源文件。执行该命令时,收到以下错误:

代码语言:javascript
复制
me@myserver:~$ shellcheck -x start.sh
unrecognized option `-x'

Usage: shellcheck [OPTIONS...] FILES...
  -e CODE1,CODE2..  --exclude=CODE1,CODE2..  exclude types of warnings
  -f FORMAT         --format=FORMAT          output format
  -s SHELLNAME      --shell=SHELLNAME        Specify dialect (bash,sh,ksh)
  -V                --version                Print version information

@Bayou提到我的操作系统需要更新版本的shellcheck。我检查了我的Ubuntu16.04安装。我的服务器有shellcheck 0.3.7,这是Ubuntu16.04必须提供的最新版本,所以我从shellcheck开发人员那里获得了最新的二进制文件并安装了它。

代码语言:javascript
复制
me@myserver:~$ mkdir .work && cd .work
me@myserver:~/.work$ wget -q https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.linux.x86_64.tar.xz
me@myserver:~/.work$ ls

shellcheck-stable.linux.x86_64.tar.xz

me@myserver:~/.work$ tar xvf shellcheck-stable.linux.x86_64.tar.xz

shellcheck-stable/README.txt
shellcheck-stable/LICENSE.txt
shellcheck-stable/shellcheck

me@myserver:~/.work$ sudo chown root: shellcheck-stable/shellcheck
me@myserver:~/.work$ sudo mv /usr/bin/shellcheck .
me@myserver:~/.work$ sudo mv shellcheck-stable/shellcheck /usr/bin/
me@myserver:~/.work$ cd ../
me@myserver:~$ rm -rf .work/
me@myserver:~$ shellcheck -V

ShellCheck - shell script analysis tool
version: 0.7.1
license: GNU General Public License, version 3
website: https://www.shellcheck.net

我运行了命令shellcheck -x start.sh,并收到了零错误。

代码语言:javascript
复制
me@myserver:~$ shellcheck -x start.sh

然后,我强迫shellcheck给我一些错误。我在脚本的末尾添加了cat $myVariable

代码语言:javascript
复制
me@myserver:~$ echo "cat \$myVariable" >> start.sh  
me@myserver:~$ cat start.sh
#!/bin/bash

# shellcheck source=./.sourcefile
. .sourcefile

echo "Today is ${day}."
cat $myVariable

我测试了我的理论,shellcheck遵循了我的源代码,给了我我期待的错误。

代码语言:javascript
复制
me@myserver:~$ shellcheck -x start.sh

In start.sh line 7:
cat $myVariable
    ^---------^ SC2154: myVariable is referenced but not assigned.
    ^---------^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
cat "$myVariable"

For more information:
  https://www.shellcheck.net/wiki/SC2154 -- myVariable is referenced but not ...
  https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...

然后,我在没有-x选项的情况下执行了,而且我还收到了以下错误:

代码语言:javascript
复制
me@myserver:~$ shellcheck start.sh

In start.sh line 4:
. .sourcefile
  ^---------^ SC1091: Not following: ./.sourcefile was not specified as input (see shellcheck -x).


In start.sh line 6:
echo "Today is ${day}."
               ^----^ SC2154: day is referenced but not assigned.


In start.sh line 7:
cat $myVariable
    ^---------^ SC2154: myVariable is referenced but not assigned.
    ^---------^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
cat "$myVariable"

For more information:
  https://www.shellcheck.net/wiki/SC2154 -- day is referenced but not assigned.
  https://www.shellcheck.net/wiki/SC1091 -- Not following: ./.sourcefile was ...
  https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...

因此,shellcheck更新为最新版本,并且没有-x选项,也会给出一个错误,说明您在命令行中错过了-x选项。因此,我决定在我的start.sh中注释出源代码文件指令

代码语言:javascript
复制
me@myserver:~$ sed -i '3s/./#\ &/' start.sh
me@myserver:~$ cat start.sh
#!/bin/bash

# # shellcheck source=./.sourcefile
. .sourcefile

echo "Today is ${day}."
cat $myVariable

现在看看shellcheck怎么想

代码语言:javascript
复制
me@myserver:~$ shellcheck -x start.sh

In start.sh line 7:
cat $myVariable
    ^---------^ SC2154: myVariable is referenced but not assigned.
    ^---------^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
cat "$myVariable"

For more information:
  https://www.shellcheck.net/wiki/SC2154 -- myVariable is referenced but not ...
  https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...

哇哈那?因此,看起来我的简单脚本实际上并不需要sourcefile指令,还是shellcheck仍然看到带有数字符号的sourcefile指令被注释掉了,因为这个数字符号已经启动了sourcefile指令?因此,我完全删除了sourcefile指令,并注释掉了最后一行,它引用了源文件中没有分配的myVariable变量。

代码语言:javascript
复制
me@myserver:~$ sed -i '3d' start.sh
me@myserver:~$ sed -i '$d' start.sh
me@myserver:~$ cat start.sh
#!/bin/bash

. .sourcefile

echo "Today is ${day}."  

现在来看一下shellcheck报告的内容:

代码语言:javascript
复制
me@myserver:~$ shellcheck -x start.sh

-x选项没有错误。现在,为了检查在Ubuntu16.04上使用最新版本的shellcheck的简单shell脚本顶部是否不需要源代码文件指令,我不使用-x选项执行shellcheck

代码语言:javascript
复制
me@myserver:~$ shellcheck start.sh

In start.sh line 3:
. .sourcefile
  ^---------^ SC1091: Not following: .sourcefile was not specified as input (see shellcheck -x).


In start.sh line 5:
echo "Today is ${day}."
               ^----^ SC2154: day is referenced but not assigned.

For more information:
  https://www.shellcheck.net/wiki/SC2154 -- day is referenced but not assigned.
  https://www.shellcheck.net/wiki/SC1091 -- Not following: .sourcefile was no...

因此,简单地说,如果shellcheck没有跟踪您的源文件,那么从开发人员的github - (https://github.com/koalaman/shellcheck)中更新shellcheck并通知shellcheck有一个源代码文件可以使用-x选项,如下所示:

代码语言:javascript
复制
shellcheck -x script.sh  

我希望这能帮助到别人,因为这个网站每天都在帮助我!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-10-28 09:41:59

Shellcheck是一个静态分析工具。它不处理动态路径(基于变量或表达式)。作为另一种选择,可以考虑添加源指令。

示例:

代码语言:javascript
复制
# shellcheck source=./lib.sh
source "$(find_install_dir)/lib.sh"

source=指令告诉tells检查动态生成的文件名的位置。从这个问题来看,这应该是.sourcefile的(最有可能的,相对的)位置。

记录在https://github.com/koalaman/shellcheck/blob/master/shellcheck.1.md

票数 24
EN

Stack Overflow用户

发布于 2019-10-28 09:24:05

我使用了外壳检查0.4.4,它还说:

在start.sh第2行中:"$(pwd)"/.sourcefile ^-- SC1090:不能跟踪非常量源.使用指令指定位置。

这意味着您必须使用绝对路径,但是较新版本可能支持-P

如果您切换到一个非常量源,它也不会工作,因为.sourcefile需要一个shebang,并且您必须将这个文件与-x一起添加如下:

代码语言:javascript
复制
shellcheck -x .sourcefile start.sh

它仍然会抱怨:

Day=“星期一” ^-- SC2034:日未使用。验证或导出它。

票数 4
EN

Stack Overflow用户

发布于 2022-08-20 10:54:16

VSCode修正

在VSCode中,可以在设置中设置参数:

代码语言:javascript
复制
{
  "shellcheck.customArgs": ["-x"]
}

答:https://unix.stackexchange.com/a/534690/231320

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58587756

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档