etc./StackOverFlow

SSH를 사용하여 원격 시스템에서 로컬 쉘 스크립트를 실행하는 방법은 무엇입니까?

청렴결백한 만능 재주꾼 2023. 4. 24. 06:47
반응형

질문자 :Arun


원격 시스템에서 로컬 쉘 스크립트(windows/Linux)를 실행해야 합니다.

머신 A와 B 모두에 SSH를 구성했습니다. 내 스크립트는 머신 A에 있으며 원격 머신 B 머신에서 일부 코드를 실행할 것입니다.

로컬 및 원격 컴퓨터는 Windows 또는 Unix 기반 시스템일 수 있습니다.

plink/ssh를 사용하여 실행하는 방법이 있습니까?



머신 A가 Windows 상자인 경우 -m 매개변수와 함께 Plink(PuTTY의 일부)를 사용할 수 있으며 원격 서버에서 로컬 스크립트를 실행합니다.

 plink root@MachineB -m local_script.sh

머신 A가 Unix 기반 시스템인 경우 다음을 사용할 수 있습니다.

 ssh root@MachineB 'bash -s' < local_script.sh

스크립트를 실행하기 위해 원격 서버에 스크립트를 복사할 필요가 없습니다.


Jason R. Coombs

이것은 오래된 질문이며 Jason의 대답은 잘 작동하지만 다음을 추가하고 싶습니다.

 ssh user@host <<'ENDSSH' #commands to run on remote host ENDSSH

이것은 사용자 입력이 필요한 su 및 명령에도 사용할 수 있습니다. ( ' 이스케이프 처리된 heredoc 참고)

편집: 이 답변은 계속 약간의 트래픽을 받기 때문에 heredoc의 멋진 사용에 더 많은 정보를 추가할 것입니다.

이 구문을 사용하여 명령을 중첩할 수 있으며 이것이 중첩이 작동하는 유일한 방법입니다(제정신 방식으로)

 ssh user@host <<'ENDSSH' #commands to run on remote host ssh user@host2 <<'END2' # Another bunch of commands on another host wall <<'ENDWALL' Error: Out of cheese ENDWALL ftp ftp.secureftp-test.com <<'ENDFTP' test test ls ENDFTP END2 ENDSSH

실제로 telnet, ftp 등과 같은 일부 서비스와 대화할 수 있습니다. 그러나 heredoc은 표준 입력을 텍스트로 보내고 줄 사이의 응답을 기다리지 않는다는 것을 기억하십시오.

<<-END 를 사용하면 탭으로 내부를 들여쓸 수 있다는 것을 방금 알았습니다!

 ssh user@host <<-'ENDSSH' #commands to run on remote host ssh user@host2 <<-'END2' # Another bunch of commands on another host wall <<-'ENDWALL' Error: Out of cheese ENDWALL ftp ftp.secureftp-test.com <<-'ENDFTP' test test ls ENDFTP END2 ENDSSH

(나는 이것이 효과가 있다고 생각한다)

또한 http://tldp.org/LDP/abs/html/here-docs.html을 참조하십시오.


Yarek T

또한 대상 호스트에서 변수를 선택하려면 변수를 이스케이프하는 것을 잊지 마십시오.

이것은 과거에 나를 사로 잡았습니다.

예를 들어:

 user@host> ssh user2@host2 "echo \$HOME"

/home/user2 출력

동안

 user@host> ssh user2@host2 "echo $HOME"

/home/user 출력

또 다른 예:

 user@host> ssh user2@host2 "echo hello world | awk '{print \$1}'"

"hello"를 올바르게 출력합니다.


dogbane

이것은 인라인 원격 명령을 결합하여 로컬 시스템에서 원격 호스트로 ENV 변수를 전달하여 원격 측에서 스크립트를 매개변수화할 수 있도록 하는 YarekT의 답변에 대한 확장입니다.

 ssh user@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH' # commands to run on remote host echo $ARG1 $ARG2 ENDSSH

나는 이 모든 것을 하나의 스크립트에 보관하여 매우 읽기 쉽고 유지 관리가 용이하여 매우 유용하다는 것을 알았습니다.

이것이 작동하는 이유. ssh는 다음 구문을 지원합니다.

ssh 사용자@호스트 원격 명령

bash에서는 다음과 같이 한 줄에서 명령을 실행하기 전에 정의할 환경 변수를 지정할 수 있습니다.

ENV_VAR_1='값1' ENV_VAR_2='값2' bash -c '$ENV_VAR_1 $ENV_VAR_2 에코'

따라서 명령을 실행하기 전에 변수를 쉽게 정의할 수 있습니다. 이 경우 echo는 우리가 실행하는 명령입니다. echo 이전의 모든 것은 환경 변수를 정의합니다.

그래서 우리는 이 두 가지 기능과 YarekT의 답변을 결합하여 다음을 얻습니다.

ssh user@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'...

이 경우 ARG1 및 ARG2를 로컬 값으로 설정합니다. user@host 뒤에 있는 모든 것을 remote_command로 보냅니다. 원격 시스템이 명령을 실행할 때 ARG1 및 ARG2는 원격 서버에서 환경 변수를 정의하는 로컬 명령줄 평가 덕분에 로컬 값으로 설정된 다음 해당 변수를 사용하여 bash -s 명령을 실행합니다. 짜잔.


chubbsondubs

<hostA_shell_prompt>$ ssh user@hostB "ls -la"

hostA 사용자의 공개 키를 사용자 .ssh 디렉토리의 홈에 있는 authorized_keys 파일에 복사하지 않은 경우 비밀번호를 입력하라는 메시지가 표시됩니다. 그러면 암호 없는 인증이 허용됩니다(ssh 서버 구성에서 인증 방법으로 허용되는 경우).


Vinko Vrsalovic

보다 정교한 작업을 위해 Fabric 을 사용하기 시작했습니다. Fabric에는 Python 및 몇 가지 다른 종속성이 필요하지만 클라이언트 시스템에서만 가능합니다. 서버는 ssh 서버만 있으면 됩니다. 나는 이 도구가 SSH에 전달된 셸 스크립트보다 훨씬 강력하고 설정하는 데 어려움을 겪을 가치가 있다는 것을 알았습니다(특히 Python 프로그래밍을 즐기는 경우). Fabric은 여러 호스트(또는 특정 역할의 호스트)에서 실행 중인 스크립트를 처리하고 멱등성 작업(예: 구성 스크립트에 행 추가, 이미 있는 경우 제외)을 용이하게 하고 더 복잡한 로직(예: Python 언어 제공).


Jason R. Coombs

cat ./script.sh | ssh <user>@<host>

cglotr

ssh user@remote sh ./script.unx 실행해 보십시오.


Jeremy

"원격" 컴퓨터에 수동으로 로그인하지 않고 "로컬" 컴퓨터에서 자동으로 이 작업을 수행하고 싶다고 가정하면, Expect라고 하는 TCL 확장을 살펴봐야 합니다. 이것은 이러한 종류의 상황을 위해 정확하게 설계되었습니다. SSH를 통한 로그인/상호작용을 위한 스크립트에 대한 링크도 제공했습니다.

https://www.nist.gov/services-resources/software/expect

http://bash.cyberciti.biz/security/expect-ssh-login-script/


Dexygen

chmod +x script.sh ssh -i key-file root@111.222.3.444 < ./script.sh

Anton Kornus

나는 이것을 사용하여 원격 시스템에서 쉘 스크립트를 실행합니다(/bin/bash에서 테스트).

 ssh deploy@host . /home/deploy/path/to/script.sh

Is Ma

ssh user@hostname ".~/.bashrc;/cd path-to-file/;.filename.sh"

환경 파일(.bashrc/.bashprofile/.profile)을 소싱하는 것이 좋습니다. 대상 및 소스 호스트 환경 변수가 다를 수 있기 때문에 원격 호스트에서 무언가를 실행하기 전에.


Ankush Sahu

temp=`ls -a` echo $temp 와 같은 명령을 실행하려면 ``에서 echo $temp 명령을 실행하면 오류가 발생합니다.

아래 명령은 이 문제를 해결할 것입니다. ssh user@host ''' temp=`ls -a` echo $temp '''


Jinmiao Luo

여기( https://stackoverflow.com/a/2732991/4752883 plink 또는 ssh 사용하여 원격 Linux 시스템에서 스크립트를 실행하려는 경우 잘 작동합니다. linux 여러 줄이 있는 경우 작동합니다.

linux/windows 시스템에 있는 배치 스크립트를 실행하려고 하고 원격 시스템이 Windows 이고 **를 사용하는 여러 줄로 구성된 경우

plink root@MachineB -m local_script.bat

작동하지 않습니다.

스크립트의 첫 번째 줄만 실행됩니다. plink 의 한계일 것입니다.

솔루션 1:

여러 줄 배치 스크립트를 실행하려면(특히 몇 줄로 구성된 비교적 간단한 경우):

원래 배치 스크립트가 다음과 같은 경우

 cd C:\Users\ipython_user\Desktop python filename.py

local_script.bat 파일에서 다음과 같이 "&&" 구분 기호를 사용하여 줄을 결합할 수 있습니다 . https://stackoverflow.com/a/8055390/4752883 :

 cd C:\Users\ipython_user\Desktop && python filename.py

이 변경 후에 @JasonR.Coombs: https://stackoverflow.com/a/2732991/4752883 에서 다음과 같이 지적한 대로 스크립트를 실행할 수 있습니다.

 `plink root@MachineB -m local_script.bat`

솔루션 2:

배치 스크립트가 상대적으로 복잡한 경우 @Martin https://stackoverflow.com/a/32196999/4752883 에서 지적한 바와 같이 plink 명령과 다음을 캡슐화하는 배치 스크립트를 사용하는 것이 더 나을 수 있습니다.

 rem Open tunnel in the background start plink.exe -ssh [username]@[hostname] -L 3307:127.0.0.1:3306 -i "[SSH key]" -N rem Wait a second to let Plink establish the tunnel timeout /t 1 rem Run the task using the tunnel "C:\Program Files\R\R-3.2.1\bin\x64\R.exe" CMD BATCH qidash.R rem Kill the tunnel taskkill /im plink.exe

alpha_989

이 bash 스크립트는 대상 원격 시스템에 ssh를 수행하고 원격 시스템에서 일부 명령을 실행합니다. 실행하기 전에 예상을 설치하는 것을 잊지 마십시오(mac brew install expect )

 #!/usr/bin/expect set username "enterusenamehere" set password "enterpasswordhere" set hosts "enteripaddressofhosthere" spawn ssh $username@$hosts expect "$username@$hosts's password:" send -- "$password\n" expect "$" send -- "somecommand on target remote machine here\n" sleep 5 expect "$" send -- "exit\n"

Mohammed Rafeeq

runoverssh 를 사용할 수 있습니다.

 sudo apt install runoverssh
 runoverssh -s localscript.sh user host1 host2 host3...

-s 로컬 스크립트를 원격으로 실행


유용한 플래그:
-g 모든 호스트에 대해 전역 암호를 사용합니다(단일 암호 프롬프트).
-n sshpass 대신 SSH를 사용하여 공개 키 인증에 유용합니다.


nowat

스크립트가 짧고 스크립트 내부에 포함되어야 하고 bash 셸에서 bash 셸을 사용할 수 있는 경우 declare 을 사용하여 로컬 컨텍스트를 원격으로 전송할 수 있습니다. 리모트로 전송될 상태를 포함하는 변수와 함수를 정의하십시오. 원격 측에서 실행될 기능을 정의하십시오. bash -s 읽은 here 문서 내에서 declare -p 를 사용하여 변수 값을 전송하고 declare -f 를 사용하여 원격으로 함수 정의를 전송할 수 있습니다.

declare 은 인용을 처리하고 원격 bash 의해 구문 분석되므로 변수는 적절하게 인용되고 기능은 적절하게 전송됩니다. 로컬에서 스크립트를 작성할 수 있습니다. 일반적으로 원격 측에서 수행해야 하는 작업으로 하나의 긴 기능을 수행합니다. 컨텍스트는 직접 선택해야 하지만 다음 방법은 모든 짧은 스크립트에 대해 "충분히 양호"하고 안전합니다. 모든 코너 케이스를 적절하게 처리해야 합니다.

 somevar="spaces or other special characters" somevar2="!@#$%^" another_func() { mkdir -p "$1" } work() { another_func "$somevar" touch "$somevar"/"$somevar2" } ssh user@server 'bash -s' <<EOT $(declare -p somevar somevar2) # transfer variables values $(declare -f work another_func) # transfer function definitions work # call the function EOT

KamilCuk

하나의 스크립트라면 위의 솔루션으로 문제가 없습니다.

나는 작업을 수행하기 위해 Ansible 을 설정할 것입니다. 동일한 방식으로 작동합니다(Ansible은 ssh를 사용하여 Unix 또는 Windows용 원격 시스템에서 스크립트를 실행합니다).

보다 구조화되고 유지 관리가 용이할 것입니다.


Abhishek

로컬 스크립트가 로컬로 설정된 변수, 함수 또는 별칭을 사용하는지 여부는 불분명합니다.

이렇게 하면 다음과 같이 작동합니다.

myscript.sh:

 #!/bin/bash myalias $myvar myfunction $myvar

$myvar , myfunctionmyalias 합니다. 원격 시스템이 아닌 로컬로 설정되어 있다고 가정해 보겠습니다.

스크립트가 포함된 bash 함수를 만듭니다.

 eval "myfun() { `cat myscript.sh`; }"

변수, 함수 및 별칭 설정:

 myvar=works alias myalias='echo This alias' myfunction() { echo This function "$@"; }

그리고 "수출" myfun , myfunction , myvar , 그리고 myaliasserver 사용 env_parallel GNU 병렬에서 :

 env_parallel -S server -N0 --nonall myfun ::: dummy

Ole Tange

먼저 scp를 사용하여 스크립트를 머신 B에 복사합니다.

[user@machineA]$ scp /path/to/script user@machineB:/home/user/path

그런 다음 스크립트를 실행하십시오.

[user@machineA]$ ssh user@machineB "/홈/사용자/경로/스크립트"

스크립트에 실행 권한을 부여한 경우 작동합니다.


Community Wiki

출처 : http:www.stackoverflow.com/questions/305035/how-to-use-ssh-to-run-a-local-shell-script-on-a-remote-machine

반응형