로컬 입력 파일을 사용하여 원격 호스트에서 로컬 스크립트 실행

로컬 입력 파일을 사용하여 원격 호스트에서 로컬 스크립트 실행

여러 원격 서버에서 실행하려는 로컬 스크립트가 있습니다. 내가 사용하는 명령 구문은 다음과 같습니다.

ssh <remote_server> "bash -s" < ./local_script.sh

이것은 잘 작동하고 인수를 전달할 수도 있습니다.로컬 script.sh. 그러나 저는 다음과 같이 입력 파일을 전달하고 싶습니다.

local_script.sh < local_file.txt

이 두 가지 진술을 결합하면 다음과 같은 결과를 얻습니다.

ssh <remote_server> "bash -s" < ./local_script.sh < local_file.txt

내가 이것을 실행하면 나는 얻는다.

bash: line 1: FOO: command not found
bash: line 2: BAR: command not found
bash: line 3: BAZ: command not found
...

여기서 FOO, BAR, BAZ 등은 각 줄의 첫 번째 단어입니다.로컬 파일.txt:

FOO     FOO_PARAM1
BAR     BAR_PARAM1
BAZ     BAZ_PARAM2
...

그래서 "bash -s"원격 서버가 해석하는 것 같습니다.로컬 파일.txt입력 파일이 아닌 스크립트 파일로로컬 script.sh. 이 문제를 해결할 수 있는 방법이 있습니까(래퍼 스크립트를 만드는 것 외에)?

답변1

두 개의 독립적인 출력 스트림(stdout 및 stderr용)이 제공 되지만 ssh입력 스트림(stdin)은 하나만 제공합니다. 따라서 다른 메커니즘을 통해 스크립트 콘텐츠와 입력 파일을 전달해야 합니다.

예를 들어, 하나는 변수를 통해, 다른 하나는 stdin을 통해:

LC_CODE=$(cat local_script.sh) ssh host 'eval "$LC_CODE"' < input

( ssh클라이언트가 변수를 전달하고 LC_*( SendEnvin ssh_config) sshd서버가 이를 수락한다고 가정합니다( AcceptEnvin sshd_config))

또는 local_script.sh원격 사용자의 로그인 셸이 이 스크립트 구문에 대한 올바른 선택이라고 가정하고 의 내용을 원격 셸 코드로 전달하면 됩니다.

ssh host "$(cat local_script.sh)" < input

또는 다음과 같이 코드와 입력을 sshstdin에 연결합니다.

{
  echo '{'; cat local_script.sh; echo '}; exit'
  cat input
} | ssh host 'bash -s some arguments'

여기에서 사용 bash하면 입력을 한 번에 한 바이트씩 읽어서 다른 모든 쉘에서는 그렇지 않은 라인 bash보다 더 많이 읽지 않도록 처리합니다 .}; exit

또는 sed원격 호스트가 GNU 인 경우 sed:

echo '#END-OF-SCRIPT' | cat local_script.sh - input |
  ssh host 'set some arguments; eval "$(sed -u "/^#END-OF-SCRIPT/q")"'

(여기서 코드는 원격 사용자의 로그인 셸에 의해 평가되며 Bourne과 유사한 것으로 가정됩니다.)

답변2

BASH 'here-strings' 연산자('<<<')를 사용하는 보다 우아한 솔루션은 다음과 같습니다.

ssh -t host "/bin/bash <(base64 --decode <<<'$(base64 < script)' )"

IT는 스크립트를 가져와 Base64 문자열로 변환하고 SSH 명령으로 다시 변환한 후 파이프된 파일 이름으로 bash에 제공합니다.

대화형 셸을 구축하는 스크립트의 경우 "파이프 파일 이름" 앞에 "--rcfile"을 추가합니다.

ssh -t host "/bin/bash --rcfile <(base64 --decode <<<'$(base64 < script)' )"

자세한 내용은... https://antofthy.gitlab.io/info/apps/ssh_remote_commands.txt

답변3

이것은 잘 작동하며 여러 파일의 내용을 스크립트에 전달할 수도 있습니다.

ssh host "bash -s -- '$(cat local_file_1.txt)'  '$(cat local_file_2.txt)'" < local_script.sh

설명은 로그인 시 ssh실행 되며 bash -s스크립트 매개변수 이후의 모든 항목은 --. 그러므로 $1will의 내용은 local_file_1.txt이고, $2will의 내용은 입니다 local_file_2.txt. bash -sstdin 에서 명령을 읽습니다 < local_script.sh.

관련 정보