我有以下脚本:
installRequiredFiles=$1
install_with_pkg()
{
arg1=$1
echo $arg1
echo "[+] Running update: $arg1 update."
}
if [ $installRequiredFiles = "true" ]; then
if [ -x "$(command -v apt)" ]; then
install_with_pkg "apt"
elif [ -x "$(command -v yum)" ]; then
install_with_pkg "yum"
elif [ -x "$(command -v apk)" ]; then
install_with_pkg "apk"
else
echo "[!] Can't install files."
fi
fi
当我直接运行它时,它工作正常:
root@ubuntu:/# ./myscript.sh "true"
apt
[+] Running update: apt update.
Printing installRequiredFiles: true
Printing arg1: apt
但是当我使用时,sh -c
我收到以下错误:
root@ubuntu:/# sh -c ./myscript.sh "true"
./c.sh: 11: [: =: unexpected operator
Printing installRequiredFiles:
Printing arg1:
我希望能够正确运行它,sh -c
并且我希望它支持sh
并且bash
目前支持。
这不是
-c
选项的用途。你通常不给它一个文件,你给它shell命令。它用于执行以下操作:现在你给了它一个文件,它正在尝试读取它并执行在其中找到的命令,但是参数没有传递给脚本(
myscript.sh
),参数只提供给sh
命令本身,你可以看到只需打印参数:您需要做的就是不使用
-c
它,它会按预期工作:或者,如果您
-c
出于某种原因绝对必须使用,请将脚本和脚本的参数作为单个带引号的参数传递给sh
:您得到的错误来自
dash
外壳程序(用于/bin/sh
在您的系统上实现的外壳程序)。这是由于$installRequiredFiles
被由于变量是空的,使用它不带引号将其完全从命令中删除,这意味着该行
将被解释为
这又是
[
命令使用中的错误;=
当不需要操作员时,它会看到操作员。那么,为什么
$installRequiredFiles
(和$1
)是空的?命令
运行命令
./myscript.sh
并$0
设置为脚本中的字符串true
。in 的值$0
通常是脚本或shell 的名称,该值最常用于诊断消息(例如,在shell 产生的错误消息中)。如果你用过
相反,then
$1
会test
按预期设置为,并且$0
会设置为(这对于内联脚本sh
来说是惯用的)。在这两种情况下,脚本都将由任何不带-linesh -c
的 shell 执行脚本来执行。#!
最终运行脚本的sh
shell 可能取决于您机器上的 shell,它可能不是sh
orbash
。参见,例如,哪个 shell 解释器运行没有 shebang 的脚本?.您可能希望
#!
在脚本中添加一个 -line 指向/bin/sh
:这意味着您将能够像这样运行您的脚本:
或者,与等价的
或者,
请注意,在最后两种情况下,
sh -c
执行脚本的不是 shell,而是脚本中的#!
-line 所指的任何 shell,就像您./myscript.sh "test"
直接运行一样。与添加 -line 之前相比,不同之#!
处在于您现在可以确定这是/bin/sh
而不是其他一些 shell。该脚本仅使用 POSIX shell 语法,这意味着它可以由 执行,而不管在任何给定系统上
/bin/sh
使用什么 shell 来实现。/bin/sh
如果/bin/sh
isbash
或ksh
其他dash
更奇特的 shell 无关紧要,用户不必担心使用正确的解释器运行脚本。与此答案的各个部分相关: