ssh가 로컬이 아닌 원격 시스템에서 명령을 실행하도록 강제하는 방법

ssh가 로컬이 아닌 원격 시스템에서 명령을 실행하도록 강제하는 방법

SSH가 다음과 같은 스크립트에서 일부 명령을 실행하도록 했습니다.

#!/bin/bash

REMOTEUSER=$1
REMOTEHOST=$2    
newVh=$3

ssh "$REMOTEUSER"@"$REMOTEHOST" << EOF

cd

if [ ! -d "/data/web/someDirectory" ]
then
  echo -e "There is no vhost setup for someDirectory"
  exit 1
fi


if [ ! -d "git" ]
then
  echo -e "Home git directory not found. Creating it now."
  mkdir git
fi

if [ ! -d "git/$newVh.git" ]
then
  echo -e "Bare git repository not found for $new. Creating it now."
  mkdir git/"$newVh".git
  git init --bare git/"$newVh".git
fi


EOF

훌륭하게 작동하고 내가 원하는 것을 수행합니다. 원격 컴퓨터에 Ruby gem이 설치되어 있는지 확인하려고 하는데 compass, 없으면 설치하고 싶습니다. 스크립트 하단에 다음 줄을 추가했습니다.

.
.
.
if [ `gem list compass -i` == 'false' ]
then
  echo -e "Compass not installed... Installing it now."
  gem install compass -V
fi


EOF

하지만 `gem list compass -i`. 내 로컬 컴퓨터에서 미리 평가했습니다(나침반이 설치되어 있음). gem list compass -i출력을 보기 위해 따옴표 없이 스크립트를 실행해도 결과가 반환되는데, true이는 잘못된 것입니다. 성공하지 못한 채 여러 s로 명령을 이스케이프 처리하려고 했습니다 \.

나는 두 가지 문제가 있다고 생각합니다 :

스크립트의 다른 명령( mkdir, etc...)이 원격 시스템에서는 제대로 작동하지만 작동 cd하지 않는 이유는 무엇입니까?git initgem list

이 명령을 이스케이프 처리하여 원격으로 실행하려면 어떻게 해야 합니까?

답변1

원본 코드의 문제점은 명령이 실행되기 전에 명령 대체 표현식(백틱으로 표시됨)이 평가된다는 것입니다 ssh. 다른 상황에서는 here-doc에서 매개변수 확장을 방지하기 위해 here-doc 키워드(예: "EOF")를 인용하는 것을 고려할 수 있지만 이 경우 실제로 클라이언트 측 매개변수 대체에서 작업을 수행하려고 합니다. 따라서 여기서 해결책은 명령 대체를 피하는 것일 수 있습니다. 이 시도:

if [ \`gem list compass -i\` == 'false' ]
then
  echo -e "Compass not installed... Installing it now."
  gem install compass -V
fi

이스케이프된 백틱은 명령 대체가 평가되지 않도록 합니다.

또한 명령 대체를 위한 백틱 구문은 레거시 기능으로 널리 간주되며 현재는 달러 기호 구문이 일반적으로 선호된다는 점을 언급하고 싶습니다. 달러 기호 구문을 사용한 위의 코드 조각은 다음과 같습니다.

if [ \$(gem list compass -i) == 'false' ]
then
  echo -e "Compass not installed... Installing it now."
  gem install compass -V
fi

이 두 표기법의 차이점에 대한 자세한 내용은 다음 StackExchange 게시물을 참조하세요.

당신은 또한 볼 수 있습니다명령 대체에 대한 GNU Bash 매뉴얼 페이지.

그리고 아직 거기 있어리디렉션에 대한 GNU Bash 매뉴얼 페이지.

여기에 있는 설명서의 다음 하위 섹션에 특별한 주의를 기울이십시오.

3.6.6 여기에 문서화

이러한 유형의 리디렉션은 행에 다음 항목만 포함될 때까지 현재 소스에서 입력을 읽도록 쉘에 지시합니다.단어(후행 공백 없음) 표시됩니다. 해당 지점까지 읽은 모든 줄은 표준 입력(또는 파일 설명자)으로 사용됩니다.N만약에N지정)을 명령으로 사용합니다.

이 문서의 형식은 다음과 같습니다.

[n]<<[-]word
    here-document
delimiter

매개변수 및 변수 확장, 명령 대체, 산술 확장 또는 파일 이름 확장을 수행하지 않습니다.단어. 만약 어떤 부분이라도단어인용됐으니 그럼구분 기호따옴표를 제거한 결과입니다.단어, 여기 문서의 줄은 확장되지 않습니다. 만약에단어따옴표가 없으면 here-document의 모든 행은 매개변수 확장, 명령 대체 및 산술 확장을 거치며 문자 순서 \newline은 무시되며 '\', '$' 및 " 문자를 인용하려면 '\'를 사용해야 합니다. ".

리디렉션 연산자가 "<<-"인 경우 모든 선행 탭 문자가 입력 줄과 포함 줄에서 제거됩니다.구분 기호. 이를 통해 쉘 스크립트의 문서를 자연스럽게 들여쓰기할 수 있습니다.

관련 정보