Bash 스크립트에서 문자열을 실행하려고 합니다. 문자열에는 변수가 포함되어 있습니다(따라서 상황에 따라 일부 CLI 매개변수를 대체할 수 있음).
문제는 포함 변수를 사용할 때 --argument=value
모든 것이 충돌하여 오류가 발생한다는 것입니다.
Missing trailing-' in remote-shell command.
샘플 코드:
#!/bin/bash
rsync_path="/usr/bin/rsync -azhrP"
rsync_ssh_cmd="--rsh='ssh -o Compression=no'"
`$rsync_path /path/to/file $rsync_ssh_cmd username@localhost:/tmp`
이 코드에 마지막 문자열을 넣으면 echo
괜찮아 보입니다. 그러나 스크립트에서 문자열을 실행하려고 하면 예상대로 실행되지 않습니다.
해결책을 찾았습니다. 시도해 보면 모든 것이 괜찮을 것입니다.
eval "my-command-string"
바꾸다
`my-command-string`
또는
(my-command-string)
왜 그럴까요? 어떻게 하면 사용을 피할 수 있나요(정말로 해야 할까요?) eval
?
나는 bash 4.3.11(1)-release (x86_64-pc-linux-gnu)
(Kubuntu 14.04.3)를 사용합니다.
답변1
좋아요 eval
문자열을 두 번 평가하는 다른 방법을 찾아 이를 방지 할 수 있습니다 . 무엇을 하든 꼭 필요해요두 가지 평가귀하의 요청이파싱을 파싱하다.
내 말은:
this is 'a parsed" command string"'
^ 3으로 계산성격:
1: this 2: is 3: a parsed" command string"
3의 따옴표는 중요하지 않습니다. 전혀 중요하지 않습니다.단어의 특정 문자. '
원래 명령줄에 사용된 구문 인용문했다이는 쉘의 파서가 해석하여 분리하기 때문에 중요합니다.단어. 그 안에 있는 모든 것은 단지 단어의 일부일 뿐입니다.
그러니 얻고 싶다면더단어는 a에서 나왔습니다.하나의,준비된즉, 이를 쉘에 대한 입력으로 반환해야 합니다. 이것이 바로 쉘이 입력 시 입력 인용문을 처리하는 것입니다. 따옴표는 의미 있는 방식으로 입력을 이스케이프하고 구분하는 데 사용됩니다. Shell이 이런 식으로 계속된다면 무의미하고 꽤 무서울 것입니다. 마지막으로모두입력은 0으로 평가됩니다!
그래서 당신은두 번째 검토. 처리하지 않기 때문에 $(
명령 대체에서 얻을 수 없습니다.)
입력하다, 그들은 처리한다산출. 어떤 부작용$
단어 확장이것을 더 많은 세대와 동일시할 수도 있습니다.성격그렇지 않습니다. 즉,대지-나뉘다.대지- 분할 $IFS
하고*
와일드카드쉘에 의해 실행됨뒤쪽에입력하다성격구문 분석 중에 이미 구분되었습니다.
지금 의 전체 목적 eval
은eval
Uat~처럼입력하다쉘이 입력으로 받은 문자열입니다. 이것은정확히이것이 올바른 도구이지만, 원한다면 다른 방법으로도 할 수 있습니다.
한 가지 방법은 .
자신만의 결과물을 얻는 것입니다.
string="printf '<%s>\n' 'these are' 'some words' 'i will evaluate again'"
. /dev/fd/0 <<!
$string
!
이 예에서는 쉘평가하다~처럼입력하다그것은산출. 효과가있다:
<these are>
<some words>
<i will evaluate again>
다른 셸을 호출하여 출력을 입력으로 평가하면 됩니다.
sh -c "$string"
...결과는 동일합니다. 당신은 할 수지연쉘을 정의하여 입력하십시오 alias
.
alias evaled="$string"
evaled
...동일한 출력.
최대직접방법은 다음과 같습니다
eval "$string"
효과는 다른 모든 예제와 거의 동일하지만 이번에는 실제로 명령을 사용하여 수행했습니다.명명 된내가하고 싶은 일을 위해.
eval
사람들이 그것이 무엇을 하는지, 왜 사용해야 하는지 이해하지 못했기 때문에 나쁜 평가를 받았습니다. 문제는, 그 일의 효과를 이해하지 못한다면, 그것을 사용해서는 안 된다는 것입니다. 길을 잃기 쉽습니다. 명령이 평가됩니다.두 배— 이는 평소보다 더 많은 — 그리고하나이는 일반적으로 대부분의 사람들이 이 사이트를 탐색하기에 충분한 시간입니다.
따라서 eval
이 경우 원하는 작업을 수행하려면 을 사용해야 합니다. 왜냐하면 수행하려는 작업은 eval
문자열이기 때문입니다. 나는 판단하지 않는다왜eval
더 좋은 방법이 있었으면 좋겠지만 문자열을 원 하지만 쉘 문자열의 내용을 원할 때댓글을 달았습니다.쉘 입력으로 eval
.
답변2
포함된 따옴표로 인해 이 문제가 발생합니다.배쉬 FAQ
작업 환경은 다음과 같습니다.
#!/bin/bash
rsync_path="/usr/bin/rsync -azhrP"
rsync_ssh_cmd=(--rsh='ssh \-o Compression=no')
`$rsync_path /path/to/file $rsync_ssh_cmd root@localhost:/tmp`
[개념의 증거]
[root@localhost ~]# bash -x /tmp/c.sh
+ rsync_path='/usr/bin/rsync -azhrP'
+ rsync_ssh_cmd=(--rsh='ssh \-o Compression=no')
++ /usr/bin/rsync -azhrP /path/to/file --rsh=ssh '\-o' Compression=no root@localhost:/tmp
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/root/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /root/.ssh/id_rsa
root@localhost's password: