web-dev-qa-db-ja.com

ラッパースクリプトに渡された最初の引数は無視されます

だから私は次のスクリプトを持っています:

#!/bin/bash

echo '-------------------------'
echo $0
echo $1
echo $@
echo '-------------------------'

exec su -- someuser -c "/tmp/elasticsearch-6.4.2/bin/elasticsearch \"$@\""

/usr/bin/elasticsearch-wrapperにあります

次の引数を使用して実行すると、次のようになります。

elasticsearch-wrapper \
  -E cluster.name=elasticsearch-test-24efcbba4c68  \
  -E node.name=node-1  \
  -E http.port=9250  \
  -E path.data=/tmp/elasticsearch_test  \
  -E path.logs=/tmp/log/elasticsearch  \
  -E cluster.routing.allocation.disk.threshold_enabled=false  \
  -E network.Host=127.0.0.1  \
  -E node.attr.testattr=test  \
  -E path.repo=/tmp  \
  -E repositories.url.allowed_urls=http://snapshot.test*  \
  -E discovery.zen.minimum_master_nodes=0  \
  -E node.max_local_storage_nodes=1  \
  -E logger.level=DEBUG 

次のエラーが発生します。

root@24efcbba4c68:/app# elasticsearch-wrapper \
>   -E cluster.name=elasticsearch-test-24efcbba4c68  \
>   -E node.name=node-1  \
>   -E http.port=9250  \
>   -E path.data=/tmp/elasticsearch_test  \
>   -E path.logs=/tmp/log/elasticsearch  \
>   -E cluster.routing.allocation.disk.threshold_enabled=false  \
>   -E network.Host=127.0.0.1  \
>   -E node.attr.testattr=test  \
>   -E path.repo=/tmp  \
>   -E repositories.url.allowed_urls=http://snapshot.test*  \
>   -E discovery.zen.minimum_master_nodes=0  \
>   -E node.max_local_storage_nodes=1  \
>   -E logger.level=DEBUG
-------------------------
/usr/bin/elasticsearch-wrapper

cluster.name=elasticsearch-test-24efcbba4c68 -E node.name=node-1 -E http.port=9250 -E path.data=/tmp/elasticsearch_test -E path.logs=/tmp/log/elasticsearch -E cluster.routing.allocation.disk.threshold_enabled=false -E network.Host=127.0.0.1 -E node.attr.testattr=test -E path.repo=/tmp -E repositories.url.allowed_urls=http://snapshot.test* -E discovery.zen.minimum_master_nodes=0 -E node.max_local_storage_nodes=1 -E logger.level=DEBUG
-------------------------
cluster.name=elasticsearch-test-24efcbba4c68: -c: line 0: unexpected EOF while looking for matching `"'
cluster.name=elasticsearch-test-24efcbba4c68: -c: line 1: syntax error: unexpected end of file

したがって、$@の出力を見ると、最初の-Eオプションが何らかの理由で除外されており、エラーが発生していることがわかります。

出力は次のとおりです。

cluster.name=elasticsearch-test-24efcbba4c68 -E node.name=node-1.....

しかし、それは次のようになります。

-E cluster.name=elasticsearch-test-24efcbba4c68 -E node.name=node-1....

(最初から-Eが欠落していることに注意してください)

しかし、誰かが理由を指摘できれば、なぜそうなるのかわかりません。

4
kurupt_89

最後の行を次のように置き換えます。

exec su someuser -c '/tmp/elasticsearch-6.4.2/bin/elasticsearch "$@"' -- dummy-argv0 "$@"

通常、これはsuコマンドを介して引数を渡す方法です。

su user -c 'command "$@"' -- argv0 "$@"

Linux以外のシステムでは、--を省略してください。

マニュアルページ(su [options] [username])のsuの概要は欺瞞的です、以下はその下からのいくつかの言い回しです:

ユーザー名の後に追加の引数を指定できます。その場合、それらはユーザーのログインシェルに提供されます。

..。

-引数を使用して、シェルに提供された引数からsuオプションを分離できます。

また、すべてのechoprintf '%s\n' ...に置き換える必要があります。これは、echobashzshから組み込まれ、/bin/echoがLinuxは自分自身で-E引数を使用します( 標準 が要求するものとはまったく逆です)。一般に、echo-n-e、または-Eに展開される可能性のある変数で安全に使用する方法はありません。

注:

"$@"を使用することが、渡されたとおりに引数を保持する唯一の方法です。su -c "command $*"のバリエーションは、引数にスペースやその他の特殊文字が含まれていない場合にのみ機能します。シェル。現在の例でさえ、someuserのホームディレクトリにあるmkdir -p repositories.url.allowed_urls=http:/snapshot.test.only.ME.and.ME.and.MEによって簡単に破壊される可能性があります。

4
mosvy