원격 컴퓨터(제어할 수 없음)에서 두 개의 파일을 복사하여 액세스해야 하는 경로에 저장하는 bash 스크립트가 있습니다 root
. 여기있어:
ssh administrator@host "mkdir ${DIR}"
ssh -t administrator@host "sudo su - root -c 'cp /path/for-root-only/data1/${FILENAME} ${DIR}/'"
ssh administrator@host "mv ${DIR}/${FILENAME} ${DIR}/data1-${FILENAME}"
ssh -t administrator@host "sudo su - root -c 'cp /path/for-root-only/data2/${FILENAME} ${DIR}/'"
scp administrator@host:$DIR/{${FILENAME},data1-${FILENAME}} .
ssh administrator@host "rm -r ${DIR}"
스크립트는 동일한 비밀번호를 여러 번 묻는 메시지를 표시합니다. 다음과 같이 문서를 통해 모든 명령을 병합해 보았습니다 ssh -t
.
ssh -t administrator@host << EOF
mkdir ${DIR}
sudo su - root -c 'cp /path/for-root-only/data1/${FILENAME} ${DIR}/'
mv ${DIR}/${FILENAME} ${DIR}/data1-${FILENAME}
sudo su - root -c 'cp /path/for-root-only/data2/${FILENAME} ${DIR}/'
EOF
scp administrator@host:$DIR/{${FILENAME},data1-${FILENAME}} .
ssh administrator@host "rm -r ${DIR}"
그러나 이런 경고가 있습니다.
stdin이 터미널이 아니기 때문에 의사 터미널은 할당되지 않습니다.
비밀번호 프롬프트 수를 최소화하기 위해 이 스크립트를 작성하는 올바른 방법이 있는지 묻고 싶습니다.
답변1
SSH 연결을 열고 사용하십시오. OpenSSH의 이 기능을 마스터 연결이라고 합니다. 바라보다설정된 SSH 채널 사용
ssh_control_socket="$(mktemp)"
ssh -o ControlPath="$(ssh_control_socket)" -o ControlMaster=yes -o ControlPersist=yes administrator@host "mkdir ${DIR}"
# other commands using ssh (ssh, scp, rsync, …): pass the same ControlPath option
ssh -o ControlPath="$(ssh_control_socket)" -t administrator@host "…"
rsync -e "ssh -o 'ControlPath=$(ssh_control_socket)'" …
ssh -o ControlPath="$(ssh_control_socket)" administrator@host -O exit
rm -f "$(ssh_control_socket)"
귀찮게도 각 SSH 호출에 대해 옵션을 명시적으로 전달해야 합니다( ControlPath
각 호출과 실제 연결을 만드는 원래 SSH 클라이언트 간의 통신에 사용되는 파일 이름). ssh
여기서는 스크립트가 자체 포함되도록 명시적인 소켓 이름을 전달합니다. 종속성이 ~/.ssh/config
허용되는 경우 다음 줄을 다음 줄에 추가하세요 ~/.ssh/config
.
ControlPath ~/.ssh/%l_%h_%p_%r.multiplex
이를 통해 각 SSH 클라이언트는 기존 연결이 있는지 확인할 수 있습니다. 이 함수는 청취하는 기본 연결이 없으면 실제로 사용되지 않습니다. 첫 번째 연결에서는 여전히 전달 -o ControlMaster=yes
(또는 -M
간단하게)해야 합니다. 즉, 스크립트는 다음과 같습니다.
# Open the shared connection
ssh -M -o ControlPersist=yes administrator@host :
# … all SSH-relying commands in their basic form, they will go via the shared connection …
# Close the shared connection
ssh -O exit administrator@host
답변2
당신은 이것을 할 필요가 없습니다여기문서화( <<
이 내용의 목적은 바로 이것입니다).
당신은 간단히 할 수 있습니다ssh remotehost "command1; command2 ; command3"
예를 들어
% ssh localhost "date ; uptime ; echo hello"
sweh@localhost's password:
Tue Jul 19 08:07:48 EDT 2016
08:07:48 up 15 days, 31 min, 3 users, load average: 0.33, 0.33, 0.40
hello
그러나 scp
이 방법으로는 쉽게 병합되지 않습니다.
그래서 당신은 사용을 고려하고 싶을 수도 있습니다공개키 인증비밀번호 인증("ssh 키"라고도 함) 대신. 이것은 일반적으로 이와 같은 작업이 자동화되는 방식입니다.