![쉘 스크립트에서 변수 루프 사용](https://linux55.com/image/150678/%EC%89%98%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%97%90%EC%84%9C%20%EB%B3%80%EC%88%98%20%EB%A3%A8%ED%94%84%20%EC%82%AC%EC%9A%A9.png)
키를 사용하여 서버에 SSH를 연결하고 거기에서 많은 콘텐츠를 생성하는 다음 스크립트가 있습니다.
#!/usr/bin/env bash
ssh -i mykey.pem myuser@SERVER_IP << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
(저는 이것을 실행하는데 사용했습니다 sh scriptname.sh
)
이제 다른 서버에서 동일한 작업을 수행하고 싶기 때문에 두 개의 다른 파일( ip_1
및 ip_2
)을 사용하여 SSH를 통해 두 개의 다른 서버( 및 )에 연결해야 합니다..pem
mykey1.pem
mykey2.pem
지금까지 나는 다음과 같이 IP를 반복하는 방법을 알고 있습니다.
#!/usr/bin/env bash
ip_list="ip_1 ip_2"
for ip in $ip_list; do
ssh -i mykey.pem myuser@$ip << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done
하지만 이제는 올바른 pem 파일을 얻기 위해 반복하고 싶습니다. 이 목표를 어떻게 달성할 수 있나요? 어쩌면 또 다른 목록이 있을까요? 누군가 나에게 우아한 솔루션을 제공할 수 있습니까?
ip_1
사용해야한다mykey1.pem
ip_2
사용해야한다mykey2.pem
미리 감사드립니다
답변1
bash를 사용하고 있으므로 다음을 사용할 수 있습니다.연관 배열:
#!/usr/bin/env bash
declare -A ip_list=(["ip_1"]="mykey1.pem" ["ip_2"]="mykey2.pem")
for ip in "${!ip_list[@]}"; do
ssh -i "${ip_list[$ip]}" myuser@"$ip" << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done
ip_1
일반 인덱스 배열과 달리 연관 배열은 특정 순서로 저장되지 않으므로 이전에 처리된다는 보장이 없습니다 ip_2
.
만약 너라면필요간단한 POSIX 호환 셸을 사용하려면 ip 및 키 파일을 한 줄에 하나씩 포함하는 파일을 만듭니다.
$ cat iplist.txt
ip1 mykey1.pem
ip2 mykey2.pem
그런 다음 다음 스크립트를 사용하십시오.
#!/bin/sh
while read -r ip key; do
ssh -i "$key" myuser@"$ip" << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done
그리고 실행하세요:
sh /path/to/script < /path/to/iplist.txt
하지만 그 길로 가면스티븐의 방법더 나은.
답변2
한 가지 방법은 while IFS=, read -r
csv here 문서에서 루프를 사용하는 것입니다.
#! /bin/sh -
while IFS=, read <&3 -r ip key; do
ssh -i "$key" "$ip" << ENDSSH
...
ENDSSH
done 3<< ENDCSV
10.0.0.1,p1.pem
10.0.0.2,p2.pem
ENDCSV
그러면 사용자에게 bash를 설치하라고 요청할 필요조차 없습니다. 이식성이 문제가 되지 않으면 zsh
여러 변수에 대한 루프를 지원하는 대안을 사용할 수 있습니다.
#! /usr/bin/env zsh
for ip key (
10.0.0.1 p1.pem
10.0.0.2 p2.pem
) ssh -i $key $ip << ENDSSH
...
ENDSSH
답변3
set
원본 스크립트는 내장된 기능을 사용하여 이식성을 더욱 높일 수 있으며 IP와 키를 콜론으로 구분된 하나의 문자열로 결합할 수 있습니다. 나중에 접두사 및 접미사 제거를 사용하여 해당 항목을 추출할 수 있습니다.
#!/usr/bin/env bash
# Set positional parameters
# Example ip addresses
set -- 192.168.0.1:mykey1 192.168.1.1:mykey2
# iterating without specifying 'in' assumes positiona parameters
for host; do
ssh -i ${host##*:}.pem myuser@${host%%:*} << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done