![Bash 스크립트를 사용하여 원격으로 여러 명령 실행](https://rvso.com/image/191769/Bash%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20%EC%9B%90%EA%B2%A9%EC%9C%BC%EB%A1%9C%20%EC%97%AC%EB%9F%AC%20%EB%AA%85%EB%A0%B9%20%EC%8B%A4%ED%96%89.png)
SSH를 통해 원격 서버에 로그인하고 tmp 폴더로 이동해야 하며 거기에서 rm 명령을 실행해야 합니다. 하지만 아래 스크립트를 실행하면 원격 서버로 이동하지만 임시 폴더로 이동하지 않고 rm 명령도 실행하지 않습니다.
#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS
답변1
코드의 유일한 실제 문제는 루프에 do
및 이 부족하여 구문 오류가 발생하고 루프 변수로 done
사용하고 있지만 설정되지 않은 일부 변수와 연결을 시도한다는 것입니다.i
server
그 외에도 cat
인용되지 않은 명령 대체를 사용하고 있습니다.일반적으로공백과 파일 이름 글로빙 문자 없이 문자열을 읽을 것이라는 확신이 없다면 나쁜 생각입니다(그러나 대부분의 호스트 이름은 이 점에서 잘 작동합니다).
대부분의 경우 다음과 같이 입력을 한 줄씩 읽는 것이 더 좋습니다.
while IFS= read -r remote; do
ssh -n "$remote" 'rm -f /tmp/log52.log'
done <list
나는 표준 입력 스트림(파일에 연결됨) 읽기를 ssh -n
중지하기 위해 여기를 사용하고 있습니다 . 이 없으면 나머지 내용을 읽고 루프는 단일 반복만 실행합니다.ssh
list
-n
ssh
list
또는 여기 문서에서 명령을 정말로 읽으려면 다음을 수행하십시오.
while IFS= read -r remote; do
ssh -T "$remote" <<'END'
rm -f /tmp/log52.log
END
done <list
ssh -T
여기서는 사용자 상호 작용이 필요한 작업을 수행하지 않으므로 의사 터미널 할당을 명시적으로 비활성화하는 데 사용하고 있습니다 . 내가 그렇게 하는 이유는 ssh
표준 입력 스트림에 데이터가 있다는 것을 알아차리고 원격 시스템에 대화형 작업을 수행할 작동하는 터미널이 없다는 것을 경고할 것이기 때문입니다. here-document에서 표준 입력 스트림을 재할당하므로 여기서는 -n
필요 하지 않습니다 .ssh
ssh
그러나 루프는 단일 명령으로 대체될 수 있습니다.
xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list
... xargs
유틸리티가 읽을 위치윤곽파일에서 명령 을 파일에서 읽은 줄로 list
바꾸고 원격 시스템에 액세스하여 특정 파일을 삭제하는 작업을 수행합니다. 삭제할 파일이 없으면 오류가 발생하지 않도록 사용하고 있습니다 .{}
ssh
rm -f
일부 구현에서는 xargs
유틸리티의 병렬 실행을 허용합니다(예: 한 번에 -P 4
최대 4개의 동시 명령을 유지함 ).ssh
답변2
#! /bin/bash
for i in `cat list`
do
echo $i
echo "-------------------------"
ssh $i "rm /tmp/log52.log"
done
단일 파일만 제거해야 하는 경우 해당 파일을 하나의 라이너로 지정하기만 하면 됩니다. 추가적으로, -f
에 추가하는 것이 도움이 될 수도 있습니다 rm
.
답변3
그런 식으로 SSH 세션의 표준 입력을 단순히 리디렉션할 수는 없습니다. 다음과 같은 오류 메시지가 표시됩니다.
stdin이 터미널이 아니기 때문에 의사 터미널은 할당되지 않습니다.
pseudotty를 강제로 할당하려면 ssh에 -tt 옵션을 사용해야 합니다. 이 시도:
#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS