그래서 다음 스크립트가 있습니다.
#!/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]
는 기만적입니다. 그 아래에 있는 일부 문구는 다음과 같습니다.
사용자 이름 뒤에 추가 매개변수를 제공할 수 있으며, 이 경우 해당 매개변수는 사용자의 로그인 쉘에 제공됩니다.
....
-- 인수를 사용하여 su 옵션을 쉘에 제공된 인수와 구분할 수 있습니다.
또한 , 및 linux 의 내장 기능은 자체 인수를 취하므로 echo
모든 s를 로 바꿔야 합니다 (printf '%s\n' ...
echo
bash
zsh
/bin/echo
-E
기준필요하다). 일반적으로 , 또는 echo
로 확장될 수 있는 변수를 안전하게 사용할 수 있는 방법은 없습니다 .-n
-e
-E
노트:
using은 "$@"
전달된 매개변수를 정확하게 보존하는 유일한 방법입니다. su -c "command $*"
using의 변형은 매개변수에 공백이나 쉘에서 해석할 수 있는 기타 특수 문자가 포함되지 않은 경우에만 작동합니다. 현재 예제도 mkdir -p repositories.url.allowed_urls=http:/snapshot.test.only.ME.and.ME.and.ME
.home 디렉토리로 인해 쉽게 깨질 수 있습니다 someuser
.