2013-07-12 10 views
7

Im Allgemeinen auf NFS-Client, wie der Mounted-Point ist nicht mehr verfügbar oder vom Server-Ende DEAD, mit dem Bash Shell Script?Linux Shell Script: Wie erkennen NFS Mount-Punkt (oder der Server) ist tot?

Normalerweise ich tun:

if ls '/var/data' 2>&1 | grep 'Stale file handle'; 
then 
    echo "failing"; 
else 
    echo "ok"; 
fi 

Aber das Problem ist, besonders wenn der NFS-Server völlig tot ist oder gestoppt wird, auch den, ls Befehl, in das Verzeichnis, auf Client-seitige gehängt wird oder gestorben. Bedeutet, das obige Skript ist nicht mehr verwendbar.

Gibt es eine Möglichkeit, dies wieder zu erkennen?

Antwort

10

"stat" Befehl ist ein etwas sauberere Weg:

statresult=`stat /my/mountpoint 2>&1 | grep -i "stale"` 
if [ "${statresult}" != "" ]; then 
    #result not empty: mountpoint is stale; remove it 
    umount -f /my/mountpoint 
fi 

Zusätzlich können Sie rpcinfo verwenden, um festzustellen, ob die Remote-NFS-Freigabe verfügbar:

rpcinfo -t remote.system.net nfs > /dev/null 2>&1 
if [ $? -eq 0 ]; then 
    echo Remote NFS share available. 
fi 

Added 2013-07-15T14 : 31: 18-05: 00:

Ich habe das weiter untersucht, da ich auch an einem Skript arbeite, das veraltete Mountpoints erkennen muss. Inspiriert von one of the replies zu „Gibt es einen guten Weg, um einen veralteten NFS-Mount zu erkennen“, denke ich, kann Folgendes der zuverlässigste Weg, zu überprüfen, für staleness eines bestimmten einhängepunkt in bash:

read -t1 < <(stat -t "/my/mountpoint") 
if [ $? -eq 1 ]; then 
    echo NFS mount stale. Removing... 
    umount -f -l /my/mountpoint 
fi 

„lesen -t1 "Konstrukt verläßt die Subshell zuverlässig, wenn der Befehl stat aus irgendeinem Grund nicht reagiert.

Added 2013-07-17T12: 03: 23-05: 00:

Obwohl read -t1 < <(stat -t "/my/mountpoint") Werke, es scheint nicht ein Weg, um seine Fehlerausgabe stumm zu schalten, wenn der Mount-Punkt abgestanden ist. Das Hinzufügen von > /dev/null 2>&1 entweder innerhalb der Untershell oder am Ende der Befehlszeile bricht es. Mit einem einfachen Test: if [ -d /path/to/mountpoint ] ; then ... fi funktioniert auch und kann in Skripts vorzuziehen. Nach vielen Tests ist es das, was ich am Ende benutzt habe.

Added 2013-07-19T13: 51: 27-05: 00:

Eine Antwort auf meine Frage "How can I use read timeouts with stat?" versehen zusätzliche Details über den Ausgang des Stat-Muting (oder rpcinfo), wenn das Ziel nicht verfügbar ist und der Befehl hängt für ein paar Minuten, bevor es sich selbst auslöschen würde. Während [ -d /some/mountpoint ] verwendet werden kann, um einen veralteten Mountpoint zu erkennen, gibt es keine ähnliche Alternative für rpcinfo. Daher ist die Verwendung der read -t1-Umleitung die beste Option. Der Ausgang der Subshell kann mit 2> & - stummgeschaltet werden. Hier ist ein Beispiel von CodeMonkey's response:

mountpoint="/my/mountpoint" 
read -t1 < <(stat -t "$mountpoint" 2>&-) 
if [[ -n "$REPLY" ]]; then 
    echo "NFS mount stale. Removing..." 
    umount -f -l "$mountpoint" 
fi 

Vielleicht jetzt diese Frage vollständig beantwortet :).

+0

Ich verwendete die veraltete NFS-Einhängepunkt-Erkennung in meinem Skript ** nfs_automount **, [jetzt auf GitHub verfügbar] (https://github.com/vwal/nfs_automount). – Ville

+3

Schöne Antwort. Ich habe gesehen, dass 'read -t1 <<(stat -t" $ MOUNT_DIR "2> & -)' einen Rückgabewert von '142' liefert. So macht '[! $? -eq 0] 'als ein Test ist wahrscheinlich besser. – psiphi75

+3

Ein weiterer Punkt: 'read -t1 <<(stat -t" $ mountpoint "2> & -)' hinterlässt einen geöffneten Datei-Handle (o.ä.) zum gemounteten Ordner. Daher wird die Mount-Option fehlschlagen, wenn Sie nicht das Flag "-l" verwenden. Sie können stattdessen 'timeout 1 stat -t "$ mountpoint">/dev/null' verwenden. Dies wird den Befehl 'stat' beenden und somit den offenen Dateizugriffsbereich beenden. – psiphi75

1

Die endgültigen Antworten von Ville und CodeMonkey sind fast korrekt. Ich bin mir nicht sicher, wie niemand das bemerkt, aber eine $ REPLY Zeichenfolge mit Inhalt ist ein Erfolg, kein Fehler. Ein leerer $ REPLY-String bedeutet also, dass das Mount veraltet ist.Somit sollte die bedingte verwenden -z, nicht -n:

mountpoint="/my/mountpoint" 
read -t1 < <(stat -t "$mountpoint" 2>&-) 
if [ -z "$REPLY" ] ; then 
    echo "NFS mount stale. Removing..." 
    umount -f -l "$mountpoint" 
fi 

ich diese mehrfach ran mit einer gültigen und ungültigen Einhängepunkt und es funktioniert. Die -n-Kontrolle gab mir umgekehrte Ergebnisse. Das Echo des Reittieres war abgestanden, als es absolut gültig war.

Auch die Doppelklammer ist für eine einfache String-Prüfung nicht notwendig.