ssh
원격으로 명령을 실행 하려고 합니다 . 하지만 호출 명령을 다음과 같은 변수로 저장합니다.
SSH_CMD="ssh -i path_to/identity"
SSH_USER=user
SSH_DST=server
dir1=dir1
dir2=dir2
이제 내가
eval $SSH_CMD $SSH_USER@$SSH_DST "mkdir $dir1 && mv $dir1 $dir2 && touch $dir2"
오류가 발생합니다(보통: mv: cannot stat 'dir1': No such file or directory
).
하지만 만약 내가:
ssh -i path_to/identity $SSH_USER@$SSH_DST "mkdir $dir1 && mv $dir1 $dir2 && touch $dir2"
이것은 작동합니다. 그래서 문제는 내가 어떻게 할 것인지인 것 같습니다 eval
. 올바른 접근 방식은 무엇입니까?
답변1
eval $SSH_CMD $SSH_USER@$SSH_DST "mkdir $dir1 && mv $dir1 $dir2 && touch $dir2"
이는 실제로 실행하는 것과 동일합니다.
eval "$SSH_CMD $SSH_USER@$SSH_DST mkdir $dir1 && mv $dir1 $dir2 && touch $dir2"
eval
단일 문자열로 가져온 인수를 연결하고 셸 명령으로 실행합니다. 특히 &&
작업이 로컬 측에서 수행되므로 쉘이 먼저 실행 ssh ... mkdir dir1
되고 성공하면 원격 호스트에서 실행 mv dir1 dir2
등이 수행되지만 로컬 호스트에서는 실행되지 않습니다 .mkdir
mv
dir1
여기서는 사용할 필요가 없습니다 eval
. 첫 번째 명령에는 필요하지 않습니다.
$SSH_CMD $SSH_USER@$SSH_DST "mkdir $dir1 && mv $dir1 $dir2 && touch $dir2"
$SSH_CMD
언제아니요인용 후 원하시는 대로 ssh
, -i
, 세 단어로 나누어서 작성해 드립니다 . path_to/identity
이것은 작동하지만 약간 불결하며 $SSH_CMD
공백이 포함된 매개변수를 포함해야 하거나 전역 문자를 사용해야 하는 경우 문제가 발생할 수 있습니다.
가변 개수의 명령 인수(예: )를 저장해야 하는 경우 SSH_CMD
배열을 사용하는 것이 좋습니다. 또한 토큰화를 방지하기 위해 다른 변수가 인용됩니다.
ssh_cmd=(ssh -i path_to/identity)
ssh_user=user
ssh_host=server
dir1=dir1
dir2=dir2
"${ssh_cmd[@]}" "$ssh_user@$ssh_host" "mkdir $dir1 && mv $dir1 $dir2 && touch $dir2"
바라보다BashFAQ 050: 명령을 변수에 넣으려고 하는데 복잡한 경우에는 항상 실패합니다!그리고변수에 저장된 명령을 어떻게 실행할 수 있나요?자세한 내용은.
답변2
여기서 사용할 이유가 없습니다 eval
. 명령에 잠재적인 구멍이 많이 생길 뿐입니다.
가능하다면 다음과 같은 변수보다는 배열에 옵션을 저장해야 합니다.
SSH_OPTS=( -i path_to/identity )
SSH_USER=user
SSH_DST=server
dir1=dir1
dir2=dir2
그럼 넌 확실히 해야 해언제나변수를 큰따옴표로 묶으십시오.
ssh "${SSH_OPTS[@]}" "${SSH_USER}@${SSH_DST}" "mkdir $dir1 && mv $dir1 $dir2 && touch $dir2"