여러 원격 서버에서 실행하려는 로컬 스크립트가 있습니다. 내가 사용하는 명령 구문은 다음과 같습니다.
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_*
( SendEnv
in ssh_config
) sshd
서버가 이를 수락한다고 가정합니다( AcceptEnv
in sshd_config
))
또는 local_script.sh
원격 사용자의 로그인 셸이 이 스크립트 구문에 대한 올바른 선택이라고 가정하고 의 내용을 원격 셸 코드로 전달하면 됩니다.
ssh host "$(cat local_script.sh)" < input
또는 다음과 같이 코드와 입력을 ssh
stdin에 연결합니다.
{
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
스크립트 매개변수 이후의 모든 항목은 --
. 그러므로 $1
will의 내용은 local_file_1.txt
이고, $2
will의 내용은 입니다 local_file_2.txt
. bash -s
stdin 에서 명령을 읽습니다 < local_script.sh
.