Mam skrypt bash, w którym tworzę i wykonuję skrypt Pythona, który używa lxml etree do analizowania przez ogromny plik xml, aby wyodrębnić następujące dane:
Dane mogą mieć wiele serwerów lub tylko jeden lub żaden, a każdy serwer będzie miał 4 wartości nazwy danych, ip, port i priorytet:
name1
1.1.1.1
port#
priority
name2
1.1.1.2
port#
priority
name3
1.1.1.3
port#
priority
Muszę przeczytać ten plik i utworzyć sshpołączenie z IP i portem określonym w pliku. Jeśli połączenie zakończy się powodzeniem do pierwszego IP, „przerwałbym”, w przeciwnym razie spróbowałbym drugiego połączenia i tak dalej ...
Obecnie mam skrypt zdefiniowany w skrypcie, który ma 2 konkretne adresy IP, które są trudne do ustawienia jako zmienne i wyglądają tak:
echo -e "n${YELLOW}Checking HOST SSH Connectivity.$NOCOLOR"
for HOST in $HOST1 $HOST2; do
ERRno=0
echo -e "${YELLOW}Attempting to connect to $HOST From $IP${NOCOLOR}"
if cat < /dev/tcp/$HOST/22 </dev/null; then
echo -e "n${CYAN}Connection To $HOST Over Port 22 From ${YELLOW}$IP ${CYAN}Seem"s Good. Starting SSH Session. ${YELLOW}To End SSH Session Hit CTRL-C.$NOCOLOR"
if ! /usr/bin/ssh -c aes256-ctr -F "$SSHCONF" -p 22 "$HOST" "$CMD" ; then
echo -e "${RED}Please Check Connectivity, SSH Session Ended.$NOCOLOR"
fi
else
echo -e "${RED}Unable to connect to $HOST, Customer should make sure Port 22 Outbound is Allowed Through Firewall from $IP to $HOST.$NOCOLOR"
ERRno=3
fi
# If we had a good session (on the 1st server), break out, we are done
[[ $ERRno -eq 0 ]] && break
if [[ $HOST != $HOST1 ]]; then
echo -e "${RED}No More Servers To Try. Unable To Establish Any SSH Session.$NOCOLOR"
exit $ERRno
else
echo -e "${YELLOW}Trying Next Server...${NOCOLOR}"
fi
done
Jednak odczytanie pliku, który może się różnić długością, powoduje, że się mylę.
Jak mogę to osiągnąć? Czy powinienem budować, tablicować i indeksować? Czy powinienem zrobić pętlę do odczytu?
Tak czy inaczej, proszę podać przykłady.
Odpowiedzi:
0 dla odpowiedzi № 1Prosta odpowiedź na „jak odczytać nieokreśloną liczbę linii” to a while
pętla.
while read -r name && read -r address && read -r port && read -r priority; do
: stuff
done <file
Bardziej powszechne rozwiązanie, zarówno dla użyteczności, jak iczytelność, to rozłożenie danych jako jeden rekord na linię, każde pole w oddzielnym tokenie (lub jeśli masz wartości pól z wieloma tokenami, użyj dedykowanego znaku separatora, takiego jak przecinek, który sprawia, że twoje wejście jest plikiem CSV) .
while read -r name address port priority; do
: stuff
done <<"__HERE"
name1 1.1.1.1 80 25
name2 1.1.1.2 119 3
name3 1.1.1.3 443 50
__HERE
Aby użyć przecinka jako separatora, (lokalnie) ustaw zmienną powłoki IFS
do przecinka.