source

Bash에서 ssh를 실행하고 여러 명령을 실행하는 가장 깨끗한 방법은 무엇입니까?

manysource 2023. 4. 15. 09:02

Bash에서 ssh를 실행하고 여러 명령을 실행하는 가장 깨끗한 방법은 무엇입니까?

ssh 에이전트가 이미 설정되어 있어 Bash 스크립트의 외부 서버에서 다음과 같은 작업을 수행할 수 있습니다.

ssh blah_server "ls; pwd;"

이제 외부 서버에서 많은 긴 명령어를 실행하려고 합니다.이 모든 것을 따옴표 사이에 넣는 것은 매우 보기 흉합니다.또, 이것을 피하기 위해서, 몇번이나 ssh'를 반복하는 것은 피하고 싶다고 생각하고 있습니다.

그럼 괄호 안에 한 번에 넣을 수 있는 방법이 있을까요?다음과 같은 것을 찾고 있습니다.

ssh blah_server (
   ls some_folder;
   ./someaction.sh;
   pwd;
)

기본적으로, 나는 그것이 깨끗하기만 하면 어떤 해결책도 만족할 것입니다.

편집

명확하게 하기 위해, 저는 이것이 더 큰 bash 스크립트의 일부라는 것을 말하고 있습니다.대본은 다른 사람이 처리해야 할 수도 있기 때문에 깨끗하게 유지하고 싶습니다.다음과 같은 한 줄의 bash 스크립트는 원하지 않습니다.

ssh blah_server "ls some_folder; ./someaction.sh 'some params'; pwd; ./some_other_action 'other params';"

왜냐하면 그것은 매우 못생기고 읽기 어렵기 때문이다.

Bash Here 문서는 어떻습니까?

ssh otherhost << EOF
  ls some_folder; 
  ./someaction.sh 'some params'
  pwd
  ./some_other_action 'other params'
EOF

코멘트에서 @Globalz에 의해 언급되는 문제를 피하기 위해 (리모트사이트에서 무엇을 하고 있는지에 따라) 첫 번째 행을 다음과 같이 치환할 수 있습니다.

ssh otherhost /bin/bash << EOF

여기서의 문서에서는 변수 치환을 실시할 수 있습니다만, 견적의 문제에 대처해야 하는 경우가 있습니다.'한계 문자열', '한계 문자열', '한계 문자열', '한계 문자열', '한계 문자열', '한계 문자열', '한계 문자열', '한계 문자열', '한계 문자열', '한계 문자열', '한계 문자열', '한계 문자열' 이렇게요. EOF변수 치환을 수행할 수 없습니다.그러나 제한 문자열을 따옴표로 묶지 않고 변수가 대체됩니다.를 들어, '하다'를 하고 있는 $NAME의 셸로 " " " " 를 할 수 있습니다.

ssh otherhost /bin/bash << EOF
touch "/tmp/${NAME}"
EOF

이 수 있습니다.otherhost당신이 할당한 모든 것의 이름으로$NAME셸 스크립트의 견적에 관한 다른 규칙도 적용되지만, 너무 복잡해서 여기에 들어갈 수 없습니다.

스크립트를 로컬로 편집한 후 ssh로 파이프합니다.

cat commands-to-execute-remotely.sh | ssh blah_server

서 ''는commands-to-execute-remotely.sh위의 목록과 같습니다.

ls some_folder
./someaction.sh
pwd;

샘플 코드를 일치시키기 위해 명령어를 단일 또는 이중 큐트 안에 랩할 수 있습니다.예를들면

ssh blah_server "
  ls
  pwd
"

두 가지 방법이 있습니다.

먼저 다음과 같은 제어 소켓을 만듭니다.

 ssh -oControlMaster=yes -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip>

명령어를 실행합니다.

 ssh -oControlMaster=no -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip> -t <yourcommand>

이렇게 하면 실제로 서버에 재접속하지 않고 ssh 명령어를 작성할 수 있습니다.

는 스크립트, 즉 스크립트를 입니다.scp그것을 주입하고 달린다.

이 작업은 다음과 같이 수행할 수도 있습니다.명령어를 스크립트로 입력합니다.이름을 commands-inc로 하겠습니다.

#!/bin/bash
ls some_folder
./someaction.sh
pwd

파일 저장

리모트 서버에서 실행합니다.

ssh user@remote 'bash -s' < /path/to/commands-inc.sh

나는 실패하지 않았다.

모든 명령어를 스크립트에 입력하면 다음과 같이 실행할 수 있습니다.

ssh <remote-user>@<remote-host> "bash -s" <./remote-commands.sh

긴 명령어에 대해 가장 깨끗한지 여부를 알 수 없지만 가장 쉬운 명령어는 확실합니다.

ssh user@host "cmd1; cmd2; cmd3"

다른 파일을 포함할 필요가 없기 때문에 스크립트 작성에 적합합니다.

#!/bin/bash
ssh <my_user>@<my_host> "bash -s" << EOF
    # here you just type all your commmands, as you can see, i.e.
    touch /tmp/test1;
    touch /tmp/test2;
    touch /tmp/test3;
EOF

# you can use '$(which bash) -s' instead of my "bash -s" as well
# but bash is usually being found in a standard location
# so for easier memorizing it i leave that out
# since i dont fat-finger my $PATH that bad so it cant even find /bin/bash ..

SSH 및 Bash에서의 여러 명령어 실행

문자열 내에 세미콜론이 포함된 개별 명령어 에코로 전달되며 모두 ssh 명령어로 연결됩니다.예를 들어 다음과 같습니다.

echo "df -k;uname -a" | ssh 192.168.79.134

Pseudo-terminal will not be allocated because stdin is not a terminal.
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda2       18274628 2546476  14799848  15% /
tmpfs             183620      72    183548   1% /dev/shm
/dev/sda1         297485   39074    243051  14% /boot
Linux newserv 2.6.32-431.el6.x86_64 #1 SMP Sun Nov 10 22:19:54 EST 2013 x86_64 x86_64 x86_64 GNU/Linux

여러 줄의 문자열과 여러 bash 스크립트를 사용하여 게시된 답변이 나에게는 작동하지 않았습니다.

  • 긴 여러 줄의 문자열은 유지하기가 어렵습니다.
  • 개별 bash 스크립트는 로컬 변수를 유지하지 않습니다.

다음은 로컬 컨텍스트를 유지하면서 ssh 및 여러 명령을 실행하는 기능적인 방법입니다.

LOCAL_VARIABLE=test

run_remote() {
    echo "$LOCAL_VARIABLE"
    ls some_folder; 
    ./someaction.sh 'some params'
    ./some_other_action 'other params'
}

ssh otherhost "$(set); run_remote"

나처럼 비틀거리는 사람을 위해 세미콜론과 줄바꿈을 피하는 데 성공했습니다.

첫 번째 순서: 세미콜론.이렇게 하면 ssh 명령어는 중단되지 않습니다.

ssh <host> echo test\;ls
                    ^ backslash!

리모트 호스트 / 홈디렉토리(루트로 로그인)를 표시.

ssh <host> echo test;ls
                    ^ NO backslash

에, 현재의 작업 디렉토리를 나타냅니다.

다음 단계: 회선을 분할합니다.

                      v another backslash!
ssh <host> echo test\;\
ls

리모트 작업 디렉토리가 다시 리스트 되었습니다.포맷이 개선되었습니다.

ssh <host>\
  echo test\;\
  ls

여기보다 더 좋은 문서나 깨진 선 주위에 인용문이 있다면 - 글쎄, 내가 결정할 게 아니라...

(bash 사용, Ubuntu 14.04 LTS).

기본적으로 멀티플렉싱을 사용하여 단일 ssh 세션을 사용하도록 시스템을 설정하는 가장 쉬운 방법입니다.

소켓용 폴더를 만들면 됩니다.

mkdir ~/.ssh/controlmasters

그런 다음 .ssh 설정에 다음을 추가합니다.

Host *
    ControlMaster auto
    ControlPath ~/.ssh/controlmasters/%r@%h:%p.socket
    ControlPersist 10m

이제 코드를 수정할 필요가 없습니다.이것에 의해, 복수의 세션을 작성하지 않고, 복수의 콜을 ssh 및 scp 할 수 있게 됩니다.이것은 로컬머신과 리모트머신 사이에 더 많은 상호작용이 필요한 경우에 도움이 됩니다.

@http://http://www.cyberciti.biz/faq/linux-unix-osx-bsd-ssh-multiplexing-to-speed-up-ssh-connections/ 와 https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing 의 답변에 감사드립니다.

Bash에서 ssh를 실행하고 여러 명령을 실행하는 가장 깨끗한 방법은 무엇입니까?

이 이스케이프 기능을 사용할 것을 권장합니다.함수는 이스케이프하는 함수라는 하나의 인수를 사용합니다. ★★★★★★★★★★★★★★★.sshqfunc출력declare -f함수를 호출하는 문자열을 출력합니다."$@"적절한 인용을 하다.그럼 전체는"%q"따옴표와bash -c가 추가되었습니다.리모트에 bash가 없는 경우 bash를 sh로 변경할 수 있습니다.

sshqfunc() { echo "bash -c $(printf "%q" "$(declare -f "$@"); $1 \"\$@\"")"; };

그런 다음 원격에서 수행할 작업을 사용하여 함수를 정의합니다.함수는 정상적으로 정의되어 있기 때문에, 적절히 「깨끗하게」 됩니다.이러한 기능은 로컬로 테스트할 수 있습니다.정의 후 적절하게 이스케이프된 함수가 리모트로 전달됩니다.

work() {
   ls
   pwd
   echo "Some other command"
}

ssh host@something "$(sshqfunc work)"

Passing(통과) 인수를 전달할 수도 있으며, 이러한 인수는 위치 인수로 함수에 전달됩니다.함수 뒤의 오른쪽 다음 인수가 할당됩니다.$0- 보통 플레이스 홀더와 같은--또는_는 인수와 콜을 분리하기 위해 사용됩니다.

work() {
   file=$1
   num=$2
   ls "$file"
   echo "num is $num"
}

ssh host@something "$(sshqfunc work)" -- /this/file 5

단, 매직 문자가 있는 경우에는 인수도 적절히 따옴표로 묶어야 합니다.

ssh host@something "$(sshqfunc work)" -- "$(printf "%q" "$var1" "$var2")"

간단한 명령의 경우 다음을 사용할 수 있습니다.

ssh <ssh_args> command1 '&&' command2

또는

ssh <ssh_args> command1 \&\& command2

언급URL : https://stackoverflow.com/questions/4412238/what-is-the-cleanest-way-to-ssh-and-run-multiple-commands-in-bash