标签: shellcheck

Bash:“屏蔽返回值”是什么意思?

shellcheck 产生了以下警告

SC2155: Declare and assign separately to avoid masking return
values
Run Code Online (Sandbox Code Playgroud)

对于这行代码

local key_value=$(echo "$current_line" | mawk '/.+=.+/ {print $1 }')
Run Code Online (Sandbox Code Playgroud)

“屏蔽返回值”是什么意思,它与上述警告有什么关系?

bash shell-script shellcheck

12
推荐指数
1
解决办法
3135
查看次数

ShellCheck 抱怨我的表达式实际上不是双引号;为什么?

我正在使用 AWS CLI 编写 bash 脚本,并shellcheck给出了一个我认为不正确的错误。我想弄清楚为什么它会吹毛求疵。

这是代码和错误消息:

for server in $(${aws} ec2 describe-instances --query 'Reservations[].Instances[][].{Name: Tags[?Key==`Name`].Value[] | [0]}' --filters "Name=tag:Name,Values=${server_name}*" --output text);
                                                                                                                                                                            ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that.
Run Code Online (Sandbox Code Playgroud)

我无法让代码在 SO 编辑器中正确排列,但^--指向*代码中的 。这部分:

"Name=tag:Name,Values=${server_name}*"
Run Code Online (Sandbox Code Playgroud)

该错误提供了一个指向 ShellCheck 文档的链接以供参考,但是当我仔细检查所有内容时,看起来我符合要求。:D

我猜这*是在扔东西,我知道我可以通过这样做来解决这个问题,shellcheck -e SC2016但我真的很想知道是什么导致了 shellcheck 出现了鲤鱼。

有任何想法吗?

shell bash shell-script shellcheck

9
推荐指数
1
解决办法
963
查看次数

bash shellcheck 问题与括号扩展中的变量

我正在尝试基于两个变量并使用大括号扩展创建一个文件名数组,如下所示:

#!/bin/bash
altdir=/usr
arg=abc
tries=({.,$altdir}/{$arg,$arg/main}.{tex,ltx,drv,dtx})
for i in "${tries[@]}"; do echo $i; done
Run Code Online (Sandbox Code Playgroud)

最后一条语句正确列出了我想要的文件:

./abc.tex
./abc.ltx
./abc.drv
./abc.dtx
./abc/main.tex
./abc/main.ltx
./abc/main.drv
./abc/main.dtx
/usr/abc.tex
/usr/abc.ltx
/usr/abc.drv
/usr/abc.dtx
/usr/abc/main.tex
/usr/abc/main.ltx
/usr/abc/main.drv
/usr/abc/main.dtx
Run Code Online (Sandbox Code Playgroud)

但是 shellcheck 告诉我,altdir 和 arg 这两个变量似乎未使用:

$ shellcheck testscript

In testscript line 3:
    altdir=/usr
    ^-- SC2034: altdir appears unused. Verify it or export it.

In testscript line 4:
    arg=abc
    ^-- SC2034: arg appears unused. Verify it or export it.
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?

shell bash brace-expansion shellcheck

7
推荐指数
1
解决办法
1575
查看次数

a="$@" 的意外结果

我在这种情况下苦苦挣扎:

$ set -- 1 2 3
$ a="$@"
$ echo "$a"
1 2 3
Run Code Online (Sandbox Code Playgroud)

我觉得出乎意料的是作业本身。

man bash关于"$@"扩展是这样说的:

当扩展发生在双引号内时,每个参数都扩展为一个单独的词。

所以这应该类似于:

b="1" "2" "3"
bash: 2: command not found
Run Code Online (Sandbox Code Playgroud)

这就是"$*"扩展的目的,我收集:

当扩展发生在双引号内时,它扩展为单个单词,每个参数的值由 IFS 特殊变量的第一个字符分隔。也就是说,“$*”等价于“$1c$2c...”,其中c是IFS变量值的第一个字符。如果未设置 IFS,则参数以空格分隔。如果 IFS 为空,则连接参数时不插入分隔符。

所以这应该是正确的:

$ set -- 1 2 3
$ a="$*"
$ echo "$a"
1 2 3
Run Code Online (Sandbox Code Playgroud)

那么为什么"$@"产量相同呢?他们应该在这一点上有所不同。这是 Bash 问题还是我的误解?

Shellcheck 将其检测为SC2124。我还可以提供一个触发SC2145的示例。

观察到:

GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
4.9.0-6-amd64 #1 SMP Debian 4.9.82-1+deb9u3 (2018-03-02) x86_64 …
Run Code Online (Sandbox Code Playgroud)

bash array string assignment shellcheck

7
推荐指数
1
解决办法
266
查看次数

Shellcheck 批准了一种将一个变量中的 2 个参数传递给 bash 脚本中的命令的方法

在 bash 脚本中,我调用另一个程序,但我想使用命令行选项配置该程序。以下作品:

\n
AREA_ARG=""\nif __SOME_SETTING__ ; then\n  AREA_ARG=" --area us,ca "\nfi\n\nprocess_data -i /some/path $AREA_ARG\n
Run Code Online (Sandbox Code Playgroud)\n

即 bash 执行process_data -i /some/path, 或process_data -i /some/path --area us,ca

\n

然而shellcheck抱怨!

\n
$ shellcheck test.sh \n\nIn test.sh line 7:\nprocess_data -i /some/path $AREA_ARG\n                           ^-------^ SC2086: Double quote to prevent globbing and word splitting.\n\nDid you mean: \nprocess_data -i /some/path "$AREA_ARG"\n\nFor more information:\n  https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...\n
Run Code Online (Sandbox Code Playgroud)\n

我理解原理,但我希望/需要变量在空间上分割,以便process_data获得 2 …

bash shell-script shellcheck

6
推荐指数
2
解决办法
1950
查看次数

如果 !<命令> (...) 与 <命令> ;如果 [ $? -eq 0] (...)

我正在编写 shell 脚本,并决定通过shellcheck.net检查我的工作。我能够在脚本中获得以下两行的功能相同的行为:

findmnt /dev/sda1 >/dev/null ; if [ $? -eq 0 ]; then echo 1; else echo 0; fi
Run Code Online (Sandbox Code Playgroud)

if ! findmnt /dev/sda1 >/dev/null; then echo 0; else echo 1; fi
Run Code Online (Sandbox Code Playgroud)

然而 shellcheck会抛出

SC2181:直接使用“if mycmd;”检查退出代码,而不是间接使用$?。

我并不清楚该使用哪个。我确实看到: https: //github.com/koalaman/shellcheck/issues/1167似乎已针对几个可能的值对此进行了修改。我想确保我正在编写的内容使用最佳实践,并且可以毫无问题地运行并准确报告。

scripting control-flow shellcheck

5
推荐指数
1
解决办法
4327
查看次数

为什么在将字符串变量作为命令运行时不能引用它?

我的基于 Ubuntu/Debian 的 Linux 更新 POSIX shell 脚本似乎要求我不要用正在执行的存储命令双引号字符串变量。由于我不明白这个问题,所以想请问这是为什么?如果代码是正确的呢?

警告:SC2086,wiki,“双引号可防止通配和分词。”

脚本如下,突出显示有问题的部分:

#!/bin/sh

# exit script when it tries to use undeclared variables
set -u

# color definitions
readonly red=$(tput bold)$(tput setaf 1)
readonly green=$(tput bold)$(tput setaf 2)
readonly yellow=$(tput bold)$(tput setaf 3)
readonly white=$(tput bold)$(tput setaf 7)
readonly color_reset=$(tput sgr0)
# to create blocks of texts, I separate them with this line
readonly block_separator='----------------------------------------'

step_number=0
execute_jobs ()
{
    while [ ${#} -gt 1 ]
    do
        job_description=${1}
        job_command=${2} …
Run Code Online (Sandbox Code Playgroud)

shell quoting shellcheck

4
推荐指数
1
解决办法
596
查看次数

寻找匹配的“”问题时出现意外的 EOF

我需要一些帮助来找出我的代码出了问题的地方。代码如下:

servers=( Sanger )   
races=( American African Asian)
jobbs=( NCBI )      
ranges=( 1-2, 2-3, 3-4 )

for server in "${servers[@])"
do

for job in "${jobbs[@]}"
do


for race in "${races[@]}"
do

for range in "${ranges[@]}"
do

cd ${RESULTS}
cd "$server"
cd "$job"
cd "$race"
cd "$range"

for CHR in {1..22}
do

mv -v "$CHR".vcf.gz chr"$CHR".dose.vcf.gz
mv -v "$CHR".vcf.gz.csi chr"$CHR".dose.vcf.gz.csi

done   # chromo

done   # range

done   # race

done   # job

done   # server
Run Code Online (Sandbox Code Playgroud)

我的 Bash 终端返回错误:

./rename.sh: line 41: …
Run Code Online (Sandbox Code Playgroud)

linux shell bash shellcheck

4
推荐指数
1
解决办法
2万
查看次数

在 Bash 中双引号和不双引号数组有什么区别?

在跟踪我的 shellscript 中的错误时,我在此代码片段中发现了以下行为:

declare -a filelist
readarray filelist < <(ls -A)
readonly filelist
for file in "${filelist[@]}"; do
  sha256sum ${filelist[$file]} | head -c 64
done
Run Code Online (Sandbox Code Playgroud)

当数组filelist不在双引号中时,命令成功。我一直在使用 ShellCheck 来尝试改进我的编码,它建议-

双引号以防止通配和分词。

在这种情况下,我不担心分词,但在很多其他情况下我很担心,所以我试图保持我的代码一致。但是,当我双引号数组时,命令失败。将代码简化为单个元素可得到以下结果:

bash-5.0# sha256sum ${filelist[0]} | head -c 64
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

bash-5.0# sha256sum "${filelist[0]}" | head -c 64
sha256sum: can't open 'file1
': No such file or directory
Run Code Online (Sandbox Code Playgroud)

我显然可以......不是双引号,因为在这种情况下分词不是问题。但我想发帖,因为将来可能会。

我的问题有两个部分:

  1. 除了上面的双引号数组之外,是否有“最佳实践”方法来防止分词?
  2. 数组中的单引号来自哪里? 编辑:没有单引号。单引号是显示无法打开的文件名的错误。

另外,出于好奇,为什么不echo ${filelist[0]}包含额外的换行符,但是echo "${filelist[0]}"呢?

shell bash array brace-expansion shellcheck

4
推荐指数
2
解决办法
923
查看次数

关于引用 ("A"B"C") 的 ShellCheck 警告

我正在编写简单的 shell 脚本,当我在https://www.shellcheck.net检查我的脚本时,它在第 14 行出现错误

Line 14:
  sysrc ifconfig_"${Bridge}"="addm ${NIC}"
                            ^-- SC2140: Word is of the form "A"B"C" (B indicated). Did you mean "ABC" or "A\"B\"C"?
Run Code Online (Sandbox Code Playgroud)

https://github.com/koalaman/shellcheck/wiki/SC2140

事实上我不明白如何纠正它

#!/bin/sh

Setup() {
  # Determine interface automatically
  NIC="$(ifconfig -l | awk '{print $1}')"
  # Enabling the Bridge
  Bridge="$(ifconfig bridge create)"
  # Next, add the local interface as member of the bridge.
  # for the bridge to forward packets,
  # all member interfaces and the bridge need to be up:
  ifconfig …
Run Code Online (Sandbox Code Playgroud)

shell-script quoting shellcheck

4
推荐指数
1
解决办法
410
查看次数