위치 인수만 실행하는 스크립트가 있습니다. (저는 보안 위험을 알고 있으며 이 스크립트는 최소한의 작업 예제이므로 어떤 목적으로도 사용되지 않습니다.)
$ cat script
> #!/usr/bin/env bash
>
> eval "${*}"
$ cat "docu ment"
> Lorem ipsum dolor sit amet
내가 하고 싶은 것은 or ./script cat "docu ment"
를 사용하여 스크립트를 호출하는 것입니다. ./script cat docu\ ment
그러나 따옴표나 이스케이프 문자가 사라지고 스크립트가 시도 cat docu ment
하지만 작동하지 않습니다. 이 경우 참조를 어떻게 수정할 수 있나요?
편집: 제가 정말로 원하는 것은 성공적인 종료 코드를 반환할 때까지 명령을 여러 번 호출하거나 n번 시도하는 것입니다. 내 스크립트는 다음과 같습니다
#!/usr/bin/env bash
# Try command several times, until it reports success (exit code 0)
# or I give up (tried n times)
tryMax=10
try=1
# Do until loop in bash
while
eval "${@}"
exitcode="${?}"
[[ "${exitcode}" -ne 0 && "${try}" -lt "${tryMax}" ]]
do (( try++ ))
done
if [[ "${exitcode}" -ne 0 ]]; then
echo -n "I tried hard, but did not manage to make this work. The exit code "
echo "of the last iteration of this command was: ${exitcode}."
exit "${exitcode}"
fi
답변1
여기서는 필요하지 않습니다 eval
. 다음을 사용할 수 있습니다 "$@"
.
while
"${@}"
exitcode="${?}"
[[ "${exitcode}" -ne 0 && "${try}" -lt "${tryMax}" ]]
do ...
"$@"
스크립트의 모든 매개변수를 별도의 "단어"로 확장합니다.- 차단된 원본 참조를 존중합니다.분사- 그런 다음실행을 기다리는 명령으로 첫 번째 인수를 사용할 수 있습니다.( cat
), 나머지 매개변수는 cat
( docu ment
)의 매개변수로 사용된다.
작동하지 않는 경우:
"$@"
들어오는 명령이 파이프, 함수 정의, 루프 등과 같은 다른 더 높은 수준의 셸 구성을 사용하도록 하려는 경우 이는 매개변수 확장 전에 처리되며 확장 후에는 다시 시도되지 않습니다.- 명령의 반환 코드가 무효화된 경우
! cmd
.!
또한 매개변수 확장 전 처리 명령 시작 시 처리됩니다. - 명령이 여러 명령인 경우
x \; y
or 또는$'x\ny'
, or는x $'\n' y
or와 같습니다. 이 모든 것은 단지 일상적인 주장일 뿐입니다.&&
||
- 명령 앞에 변수 할당이 있는 경우 예를 들어
LD_LIBRARY_PATH=/x foo
변수를 스크립트 이름 앞에 넣을 수 있지만 매개변수 명령 앞에는 넣을 수 없습니다. - 명령에 리디렉션이 있으면 그 안에 있는
>foo
것 입니다.3<bar
스크립트에는 자체 로그 출력이 있으므로 이러한 내용은 스크립트에 첨부될 수도 있고 첨부되지 않을 수도 있습니다. - 명령에 여기에 문서가 있거나 여기에 문자열이 있는 경우. 스크립트 자체에 첨부된 경우 한 번만 읽을 수 있으므로 명령이 실패한 정확한 시점에 따라 괜찮을 수도 있고 그렇지 않을 수도 있습니다. 어쨌든, 이것들은 적절하게 전달하기가 어렵습니다
eval
. - 명령이 서브쉘
( ... )
또는 명령 그룹 인 경우{ ... ; }
. 이는 문법적 구성이 아닌(
and 라는 명령으로 처리됩니다 .{
- 명령에 다음이 포함된 경우명령 대체
$(...)
반복적으로 실행해야 함. 이(또는 다른 쉘 구성)을 사용하여 원시 인수를 생성할 수 있지만 일단 스크립트가 실행되기 시작하면 모두 고정된 문자열이 됩니다. - 명령에 반복적으로 평가해야 하는 다른 요소가 있는 경우(예:
$RANDOM
또는산술 확장$((i++))
. - 명령이
time
.아니요따라서 내장 명령도 매개변수 확장 전에 처리됩니다.
그러나 그렇지 않으면 성공적으로 eval
이를 완전히 피할 수 있으며 그렇게 해야 합니다. 가능한 보안 문제를 무시하더라도 올바르게 구축하는 것은 매우 취약합니다.