我在 Ubuntu 18.04.4 LTS 上的 shellcheck 上看到了这个问题:
$ ls -l /data/myscript
-rwxr-xr-x 1 user 1300000013 4200 Aug 25 13:13 /data/myscript
$ shellcheck /data/myscript
/data/myscript: /data/myscript: openBinaryFile: does not exist (No such file or directory)
Run Code Online (Sandbox Code Playgroud)
为什么会出现错误?
我正在尝试使用 Shellcheck 对 shell 脚本进行静态代码分析。我想知道用于执行分析的规则。我在哪里可以得到它们?
以下是我从简单的 helloworld 程序获得的示例输出:
In C:\Users\~\Desktop\hello.sh line 1:
#!/bin/sh
^-- SC1017: Literal carriage return. Run script through tr -d '\r' .
In C:\Users\~\Desktop\hello.sh line 2:
# This is a comment!
^-- SC1017: Literal carriage return. Run script through tr -d '\r' .
Run Code Online (Sandbox Code Playgroud) 我的脚本中有以下一组命令:
message="Secure copying file $remoteHost"
backupLogOutput "Info $message"
$(scp "$file" "$remoteUser"@"$remoteHost":"$remotePath") >> "$BACKUPLOG"
backupErrorHandler "$?" "$message"
Run Code Online (Sandbox Code Playgroud)
ShellCheck 在 scp 行 (3) 上向我发出警告:
删除周围的 $() 以避免执行输出。[SC2091]
该脚本有效。我确实想执行输出。我应该忽略这个警告还是应该以不同的方式编写 scp 行?
我正在寻找一个单行代码来替换变量字符串中变量字符串中变量位置的任何字符。我想出了这个工作解决方案:
echo "$string" | sed "s/./${replacement}/${position}"
Run Code Online (Sandbox Code Playgroud)
示例用法:
string=aaaaa
replacement=b
position=3
echo "$string" | sed "s/./${replacement}/${position}"
aabaa
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我使用包含我当前解决方案的脚本运行 shellcheck 时,它告诉我:
SC2001: See if you can use ${variable//search/replace} instead.
Run Code Online (Sandbox Code Playgroud)
我想使用它建议的参数扩展而不是管道到 sed,但我不清楚使用位置变量时的正确格式。在官方文档似乎并没有讨论在所有字符串中的定位。
这可能吗?
在允许变量赋值中的 ${@:2} 语法上,他们说我不应该使用,"${@:2}"因为它破坏了不同 shell 的内容,而我应该使用它"${*:2}"。
但是,使用"${*:2}"的,而不是"${@:2}"完全是无稽之谈,因为这样做"${@:2}"不等同于"${*:2}"如下面的例子:
#!/bin/bash
check_args() {
echo "\$#=$#"
local counter=0
for var in "$@"
do
counter=$((counter+1));
printf "$counter. '$var', ";
done
printf "\\n\\n"
}
# setting arguments
set -- "space1 notspace" "space2 notspace" "lastargument"; counter=1
echo $counter': ---------------- "$*"'; counter=$((counter+1))
check_args "$*"
echo $counter': ---------------- "${*:2}"'; counter=$((counter+1))
check_args "${*:2}"
echo $counter': ---------------- "${@:2}"'; counter=$((counter+1))
check_args "${@:2}"
Run Code Online (Sandbox Code Playgroud)
-->
GNU bash, version 4.4.12(1)-release …Run Code Online (Sandbox Code Playgroud) 我在我的脚本上运行shellcheck并且经常收到这个警告(在这种情况下是正确的,因为cd foo bar baz没有意义):
cd ${SOME_DIR} || exit 1
^-- SC2046: Quote this to prevent word splitting.
Run Code Online (Sandbox Code Playgroud)
这个警告主要是一个好的警告。变量包含多个参数时的一种例外情况:
gcc ${OPTIONS} ...
^-- SC2046: Quote this to prevent word splitting.
Run Code Online (Sandbox Code Playgroud)
是否有关于故意分词的约定更明确,可能会避免此 shellcheck 警告?
如何重写以下bash命令以使ShellCheck兼容?
memory=$(cat /proc/meminfo | grep 'MemTotal:' | awk {'print $2}' 2> /dev/null)
Run Code Online (Sandbox Code Playgroud)
它目前抱怨:
我有这个脚本:
#!/bin/bash
list="a b c d"
for item in ${list[@]}; do
echo "${item}"
done
Run Code Online (Sandbox Code Playgroud)
当我运行它时,这是输出:
a
b
c
d
Run Code Online (Sandbox Code Playgroud)
这正是我想要的.但是,shellcheck讨厌这个并抛出一个错误:
for item in ${list[@]}; do
^-- SC2068: Double quote array expansions to avoid re-splitting elements.
Run Code Online (Sandbox Code Playgroud)
但是,当我双引号变量时,脚本的输出更改为:
a b c d
Run Code Online (Sandbox Code Playgroud)
这不是我想要的.
shellcheck是否正确,我应该修改我尝试从变量中提取项目的方式,但是如何?或者我应该告诉shellcheck忽略这一点?