방금 한 컴퓨터에서 다른 컴퓨터로 ssh -t를 사용하여 명령을 실행할 수 있다는 사실을 (뒤늦게) 발견했습니다.
그런 다음 다음과 같은 작업을 수행하여 컴퓨터의 로그 파일을 한 쌍으로 추적하는 스크립트를 만들 수 있어야 한다는 생각이 들었습니다.
ssh -t $1 ssh -t $2 tailf /pathtofile/$3/log.log
실제로 1,2,3을 수동으로 입력하면 정상적으로 작동됩니다.
내 문제는 이 작업을 수행하려면 1, 2 또는 3개의 호스트 사이를 이동해야 할 수도 있다는 것입니다.
zsh에서 어떻게 할 수 있나요? 좀 파헤쳐보니 변신이 내 친구일 것 같지만 조금 헷갈립니다.
답변1
저는 실제 사용자가 아니기 때문에 솔루션 zsh
을 작성하겠습니다 sh
(zsh
~해야 한다실행도 가능합니다)
일반적인 요점은 ssh -t hostname
마지막 항목을 제외한 각 명령줄 옵션에 대해 1비트 목록을 만든 다음 해당 목록을 명령으로 실행하는 것입니다.
#!/bin/sh
argn=$#
i=0
for arg do
shift
i=$(( i + 1 ))
if [ "$i" -lt "$argn" ]; then
set -- "$@" ssh -t "$arg"
else
set -- "$@" "/pathtofile/$arg/log.log"
fi
done
command "$@"
다음과 같이 실행하세요.
sh script.sh alpha beta gamma zeta
목록이 생성됩니다
ssh -t alpha ssh -t beta ssh -t gamma /pathtofile/zeta/log.log
스크립트의 마지막 명령은 명령으로 실행됩니다.
이 목록은 $@
스크립트 시작 부분에 있는 스크립트의 명령줄 인수를 포함하는 위치 인수 목록에 내장되어 있습니다. 루프는 원래 목록의 마지막 요소가 언제 발견되는지 추적하고 이를 특별하게 처리합니다.
이 set
명령을 위와 같이 사용하면 목록에 추가되고 shift
목록의 첫 번째 요소(현재 작업 중인 요소)가 제거됩니다.
zsh
특정 구문을 사용하면 이 내용을 더 짧고 우아하게 만들 수 있다고 확신합니다 .
답변2
나는 당신이 루프에서 쉽게 벗어날 수 없다고 생각합니다.
cmd=()
for i ($argv[1,-2]) cmd+=(ssh -t $i)
$cmd tailf /pathtofile/$argv[-1]/log.log
엄밀히 말하면, 전달하는 쉘 명령줄이므로 이러한 임의의 값을 지원할 수 있으 ssh
려면 이러한 매개변수를 인용하고 각 ssh에 인용 수준을 추가해야 합니다.$1
$2
여기서는 모든 호스트의 사용자 로그인 쉘이 Bourne과 유사하다고 가정합니다.
cmd=(tailf /pathtofile/$argv[-1]/log.log)
argv[-1]=()
while (($#argv)) {
cmd=(ssh -t "$argv[-1]" ${(j: :)${(qq)cmd}})
argv[-1]=()
}
이렇게 하면 호출 시 작동하게 됩니다.
that-script host1 host2 'dir with spaces and other nasty characters'