래퍼 스크립트에 전달된 첫 번째 인수가 무시되었습니다.

래퍼 스크립트에 전달된 첫 번째 인수가 무시되었습니다.

그래서 다음 스크립트가 있습니다.

#!/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' ...echobashzsh/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.

관련 정보