SSH를 통해 원격 서버에 로그인하고 tmp 폴더로 이동한 다음 rm 명령을 실행해야 합니다. 그런데 아래 스크립트를 실행하면 원격 서버로는 가는데 temp 폴더에는 가지 않고 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 문서에서 표준 입력 스트림을 재할당 -n
하기 때문에 여기서는 이것이 필요하지 않습니다 .ssh
ssh
그러나 루프는 단일 명령으로 대체될 수 있습니다.
xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list
... xargs
유틸리티가 읽을 위치철사파일에서 list
명령을 파일을 읽어 특정 파일을 삭제하기 위해 원격 시스템에 접속하는 동작을 수행하는 라인 {}
으로 대체합니다. 삭제할 파일이 없으면 일반적으로 오류가 발생하지 않습니다.ssh
rm -f
예를 들어 일부 구현에서는 xargs
유틸리티의 병렬 실행을 허용합니다 -P 4
(최대 ssh
4개의 동시 명령이 동시에 실행됨).
답변2
#! /bin/bash
for i in `cat list`
do
echo $i
echo "-------------------------"
ssh $i "rm /tmp/log52.log"
done
파일 하나만 삭제해야 하는 경우에는 한 줄에 간단히 지정하면 됩니다. 또한 -f
에 대한 추가 사항도 찾을 수 있습니다 rm
.
답변3
이와 같이 SSH 세션의 표준 입력을 단순히 리디렉션할 수는 없습니다. 다음과 유사한 오류 메시지가 표시됩니다.
stdin이 터미널이 아니기 때문에 의사 터미널이 할당되지 않습니다.
의사 장치 할당을 강제하려면 ssh 옵션 -tt를 사용해야 합니다. 이 시도:
#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS