GNU/Linux >> Znalost Linux >  >> Linux

Ssh způsobí, že se smyčka zastaví?

Konečně se mi podařilo vyřešit problém, se kterým jsem se potýkal několik týdnů. Ke vzdálenému spouštění příkazů používám SSH s „autorizovanými klíči“. Všechno je v pořádku, kromě případů, kdy to dělám ve smyčce while. Cyklus se ukončí po dokončení jakékoli iterace pomocí příkazu ssh.

Dlouho jsem si myslel, že jde o nějaký druh ksh podivnosti, ale nyní jsem zjistil, že bash se ve skutečnosti chová identicky.

Malý ukázkový program pro reprodukci problému. Toto je odvozeno od větší implementace, která pořizuje snímky a replikuje je mezi uzly v clusteru.

#!/bin/bash

set -x

IDTAG=".*zone"
MARKER="mark-$(date +%Y.%m.%d.%H.%M.%S)"
REMOTE_HOST=sol10-target
ZFSPARENT=rpool

ssh $REMOTE_HOST zfs list -t filesystem -rHo name,mounted $ZFSPARENT | grep "/$IDTAG    " > /tmp/actionlist

#for RMT_FILESYSTEM in $(cat /tmp/actionlist)
cat /tmp/actionlist | while read RMT_FILESYSTEM ISMOUNTED
do
   echo ${RMT_FILESYSTEM}@${MARKER}
   [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
   echo Remote Command Return Code: $?
done

(Všimněte si, že ve vyhledávacím výrazu grep je znak TAB podle definice chování volby „-H“ v seznamu zfs.)

Můj vzorek má nějaké souborové systémy ZFS pro kořen, kde všechny „zóny“ mají svůj kořenový souborový systém na datové sadě s názvem podobně jako

POOL/zones/app1zone
POOL/zones/group2/app2zone

atd.

Výše uvedená smyčka by měla vytvořit snímek pro každou z vybraných datových sad, ale místo toho funguje pouze s první a poté se ukončí.

Že program najde správný počet datových sad, lze snadno potvrdit kontrolou souboru „/tmp/actionlist“ poté, co skript existuje.

Pokud je příkaz ssh nahrazen například příkazem echo, pak smyčka prochází všemi vstupními řádky. Nebo můj oblíbený – před problematický příkaz přidejte „echo“.

Pokud místo toho použiji smyčku for, pak to také funguje, ale kvůli potenciální velikosti seznamu datových sad by to mohlo způsobit problémy s maximální rozšířenou délkou příkazového řádku.

Nyní jsem si na 99,999 % jistý, že problémy mi dělají pouze smyčky s příkazy ssh!

Všimněte si, že iterace, ve které je spuštěn příkaz ssh, je dokončena! Je to, jako by se data vložená do smyčky while náhle ztratila... Pokud prvních několik vstupních řádků neprovede příkaz ssh, pak smyčka pokračuje, dokud skutečně nespustí příkaz SSH.

Na svém notebooku, kde to testuji, mám dva virtuální počítače Solaris 10 pouze se dvěma nebo třemi ukázkovými datovými sadami, ale totéž se děje na velkých systémech SPARC, kde to má být spuštěno, a existuje mnoho datových sad.

Související:Jak změnit cron shell (sh na bash)?

Přijatá odpověď:

SSH může číst ze standardního vstupu a požírat váš seznam akcí. Zkuste přesměrovat standardní vstup ssh na /dev/null:

ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER} </dev/null

Obecně platí, že při spouštění příkazů, které mohou rušit standardní vstup pod while read -stylová smyčka, ráda zabalím celé tělo smyčky do rovnátek:

cat /tmp/uuoc | while read RMT_FILESYSTEM ISMOUNTED
do {
    echo ${RMT_FILESYSTEM}@${MARKER}
    [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
    echo Remote Command Return Code: $?
} < /dev/null; done

Linux
  1. Příklady Bash for Loop a While Loop

  2. Pomocí a ve smyčce Bash while

  3. SSH - Jak zahrnout příkaz -t do souboru ~/.ssh/config

  1. Bash Loop - Jak zastavit smyčku, když stisknu Control-C uvnitř příkazu?

  2. Příkaz Linuxu, který čeká na spuštění serveru SSH

  3. Provádění dlouhotrvajícího příkazu na ssh

  1. Jak najít aktivní připojení SSH v systému Linux

  2. Pamatujete si napůl napsaný příkaz, když něco zkontroluji?

  3. Ssh – Omezení uživatele Ssh/scp/sftp na adresář?