次のスクリプトがあります。
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
答え1
これはこのオプションの目的ではありません-c
。通常、ファイルを提供せずにシェルコマンドを提供します。その目的は、次のことを行うことです。
$ sh -c 'echo hello'
hello
これでファイルを提供し、ファイルを読み取り、そこにあるコマンドを実行しようとしましたが、パラメータはスクリプト(myscript.sh
)に渡されず、パラメータはコマンドsh
自体にのみ渡されます。パラメータ:
$ cat script.sh
echo "ARGS: $@"
$ sh ./script.sh true
ARGS: true
$ sh -c ./script.sh true
ARGS:
あなたがしなければならないことは使用しないこと-c
だけであり、期待どおりに機能します。
sh ./myscript.sh "true"
または何らかの理由で使用する必要がある場合は、-c
スクリプトを渡してください。そして一重引用符で囲まれた引数としてスクリプトのパラメータsh
:
sh -c './myscript.sh "true"'
答え2
あなたが受けているエラーは、シェルdash
(システムに実装されているシェルの場合/bin/sh
)で発生します。この$installRequiredFiles
ためです
- 空の文字列、そして
- 引用符なしで使用してください。
変数は空であるため、引用符なしで変数を使用すると、コマンドから変数が完全に削除されます。
if [ $installRequiredFiles = "true" ]; then
次のように解釈されます。
if [ = "true" ]; then
これはコマンドの再利用のバグです[
。=
予想される人がいない場合、演算子が表示されます。
では、なぜ$installRequiredFiles
(および$1
)が空ですか?
注文する
sh -c ./myscript.sh "true"
コマンドを実行し./myscript.sh
、スクリプトの文字列に設定します$0
。true
inの値は$0
通常スクリプトまたはシェルの名前であり、診断メッセージ(シェルによって生成されたエラーメッセージなど)に最も一般的に使用されます。
使ってみた方なら
sh -c ./myscript.sh sh "true"
代わりに、$1
期待どおり then が に設定され、 は (インラインスクリプトのルールです) に設定されます。どちらの場合も、スクリプトは -line なしでスクリプトを実行するすべてのシェルによって実行されます。スクリプトを実行するシェルは、コンピュータのシェルによって異なる場合があり、同じでない場合があります。たとえば、次を参照してください。test
$0
sh
sh -c
#!
sh
sh
bash
Shebangなしでスクリプトを実行するシェルインタプリタとは何ですか?。
#!
以下を指すスクリプトに行を追加できます/bin/sh
。
#!/bin/sh
# ... rest of script here ...
# ... just remember to quote all expansions ...
これは、次のようにスクリプトを実行できることを意味します。
$ ./myscript.sh test
または同じ
$ sh -c './myscript.sh "test"'
または、
$ sh -c './myscript.sh "$@"' sh test
sh -c
最後の2つのケースでは、スクリプトを実行するシェルではなく直接実行する#!
のと同じように、スクリプトの-lineが参照するシェルは何でも構いません。./myscript.sh "test"
-lineを追加する前との違いは、これが他の#!
シェルではなくシェルであることを確認できることです。/bin/sh
/bin/sh
スクリプトはPOSIXシェル構文のみを使用します。つまり、/bin/sh
特定のシステムでスクリプトを実装するために使用されるすべてのシェルで実行できます。/bin/sh
それがシェルかそれ以上にbash
エキゾチックksh
なdash
シェルかは問題ではありません。ユーザーは、スクリプトを実行するために正しいインタプリタを使用することを心配する必要はありません。
この回答のさまざまな部分に関連して: