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)
“屏蔽返回值”是什么意思,它与上述警告有什么关系?
我正在使用 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 出现了鲤鱼。
有任何想法吗?
我正在尝试基于两个变量并使用大括号扩展创建一个文件名数组,如下所示:
#!/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)
有一个更好的方法吗?
我在这种情况下苦苦挣扎:
$ 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 脚本中,我调用另一个程序,但我想使用命令行选项配置该程序。以下作品:
\nAREA_ARG=""\nif __SOME_SETTING__ ; then\n AREA_ARG=" --area us,ca "\nfi\n\nprocess_data -i /some/path $AREA_ARG\nRun Code Online (Sandbox Code Playgroud)\n即 bash 执行process_data -i /some/path, 或process_data -i /some/path --area us,ca 。
然而shellcheck抱怨!
$ 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 ...\nRun Code Online (Sandbox Code Playgroud)\n我理解原理,但我希望/需要变量在空间上分割,以便process_data获得 2 …
我正在编写 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似乎已针对几个可能的值对此进行了修改。我想确保我正在编写的内容使用最佳实践,并且可以毫无问题地运行并准确报告。
我的基于 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) 我需要一些帮助来找出我的代码出了问题的地方。代码如下:
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) 在跟踪我的 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)
我显然可以......不是双引号,因为在这种情况下分词不是问题。但我想发帖,因为将来可能会。
我的问题有两个部分:
另外,出于好奇,为什么不echo ${filelist[0]}包含额外的换行符,但是echo "${filelist[0]}"呢?
我正在编写简单的 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) shellcheck ×10
bash ×7
shell ×5
shell-script ×4
array ×2
quoting ×2
assignment ×1
control-flow ×1
linux ×1
scripting ×1
string ×1