所以我有以下脚本:
#!/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
(注意从一开始就缺失了)
但我不确定为什么会这样,如果有人能指出原因吗?
答案1
将最后一行替换为:
exec su someuser -c '/tmp/elasticsearch-6.4.2/bin/elasticsearch "$@"' -- dummy-argv0 "$@"
一般来说,这是通过命令传递参数的方式su
:
su user -c 'command "$@"' -- argv0 "$@"
--
在非 Linux 系统上您应该忽略。
su
手册页 ( ) 中的概要su [options] [username]
具有欺骗性,以下是其下面的一些措辞:
可以在用户名之后提供其他参数,在这种情况下,它们将提供给用户的登录 shell。
....
您可以使用 -- 参数将 su 选项与提供给 shell 的参数分开。
您还应该将所有echo
s 替换为printf '%s\n' ...
,因为echo
内置的 frombash
和zsh
,以及/bin/echo
from linux 将使用自己的-E
参数(与标准要求)。一般来说,没有办法安全地使用echo
可能扩展到-n
,-e
或 的变量-E
。
笔记:
using"$@"
是精确保留参数传递时的参数的唯一方法——su -c "command $*"
只有当参数不包含空格或任何其他可由 shell 解释的特殊字符时, 的任何变体才有效。即使当前的示例也可以很容易地被mkdir -p repositories.url.allowed_urls=http:/snapshot.test.only.ME.and.ME.and.ME
.home 目录中的a 破坏someuser
。