Warum wird diese Datei ausgeblendet, wenn Sie ls ausführen?

10

EDIT: Ich habe diesen Thread total vergessen. Es stellte sich heraus, dass ich eine schlechte Festplatte hatte. Wir mussten diesen Server für andere Anforderungen neu bereitstellen, damit ich endlich die eine fehlerhafte Festplatte ersetzen konnte und wir wieder im Geschäft sind.

Seit einigen Wochen konnte ich nicht herausfinden, warum ich diese eine bestimmte Datei nicht löschen konnte. Als root kann ich, aber mein Shell-Skript läuft als anderer Benutzer. Also gehe ich ls -la laufen und es ist nicht da. Wenn ich es jedoch als Parameter aufrufe, wird es angezeigt! Sicher genug, der Besitzer ist root, daher kann ich nicht löschen.

Beachten Sie, 6535 fehlt ...

[root@server]# ls -la 653*
-rw-rw-r--  1 svn svn  24002 Mar 26 01:00 653
-rw-rw-r--  1 svn svn   7114 Mar 26 01:01 6530
-rw-rw-r--  1 svn svn   8653 Mar 26 01:01 6531
-rw-rw-r--  1 svn svn   6836 Mar 26 01:01 6532
-rw-rw-r--  1 svn svn   3308 Mar 26 01:01 6533
-rw-rw-r--  1 svn svn   3918 Mar 26 01:01 6534
-rw-rw-r--  1 svn svn   3237 Mar 26 01:01 6536
-rw-rw-r--  1 svn svn   3195 Mar 26 01:01 6537
-rw-rw-r--  1 svn svn  27725 Mar 26 01:01 6538
-rw-rw-r--  1 svn svn 263473 Mar 26 01:01 6539

Jetzt wird es angezeigt, wenn Sie es direkt aufrufen.

[root@server]# ls -la 6535
-rw-rw-r--  1 root root 3486 Mar 26 01:01 6535

Hier ist etwas Interessantes. Ich habe dieses Problem festgestellt, weil es in meinem Shell-Skript nicht gelöscht werden konnte, da 6535 im Besitz von root ist. Die Datei wird tatsächlich angezeigt, nachdem ich "rm -rf" ausgeführt habe. Ich habe es früher versucht und das Verzeichnis konnte nicht entfernt werden, da mir mitgeteilt wurde, dass das Verzeichnis nicht leer ist. Ich ging hinein und schaute und sicher genug, die Datei "6535" wird endlich angezeigt. Keine Ahnung warum es so ist.

strace sagt folgendes

#strace ls -la 653* 2>&1 | grep ^open

open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib64/tls/librt.so.1", O_RDONLY) = 3
open("/lib64/libacl.so.1", O_RDONLY)    = 3
open("/lib64/libselinux.so.1", O_RDONLY) = 3
open("/lib64/tls/libc.so.6", O_RDONLY)  = 3
open("/lib64/tls/libpthread.so.0", O_RDONLY) = 3
open("/lib64/libattr.so.1", O_RDONLY)   = 3
open("/etc/selinux/config", O_RDONLY)   = 3
open("/proc/mounts", O_RDONLY)          = 3
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
open("/proc/filesystems", O_RDONLY)     = 3
open("/usr/share/locale/locale.alias", O_RDONLY) = 3
open("/usr/share/locale/en_US.UTF-8/LC_TIME/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_TIME/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_TIME/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.UTF-8/LC_TIME/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_TIME/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_TIME/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/nsswitch.conf", O_RDONLY)    = 3
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib64/libnss_files.so.2", O_RDONLY) = 3
open("/etc/passwd", O_RDONLY)           = 3
open("/etc/group", O_RDONLY)            = 3
open("/etc/mtab", O_RDONLY)             = 3
open("/proc/meminfo", O_RDONLY)         = 3
open("/etc/localtime", O_RDONLY)        = 3
Glücksaxi
quelle
2
Wenn Sie dies herausfinden, veröffentlichen Sie bitte ein Update.
einstiien
Interessant. Was wird mit ls -ab gemeldet? Vielleicht enthält der Dateiname ein ungerades nicht oktales Zeichen? Ich würde denken, ich würde es trotzdem auflisten, aber ich bin mir nicht sicher.
Egorgry
1
Hast du kürzlich einen fsck gemacht? Es ist aus der Ferne möglich, dass im Dateisystem etwas kaputt ist.
Zoredache
Ich muss es morgen noch einmal testen und gehe für den Tag.
Luckytaxi

Antworten:

7

Das ist ein bisschen besorgniserregend. Ich würde überprüfen, ob Ihre lsDatei nicht durch Vergleich mit einer bekanntermaßen guten Datei geändert wurde. Sie können die Paket-Tools Ihrer Distribution verwenden, um die Datei auf einem isolierten System zu überprüfen.

Warner
quelle
+1: ls -al sollte alles zeigen. Wenn nicht, gibt es irgendwo ein Problem.
Satanicpuppy
2
Es ist durchaus möglich, dass lsgeändert wurde, um eine bestimmte PID zu verbergen, möglicherweise 6535.
MikeyB
Nein ... nichts ...
Luckytaxi
6

Manchmal enthalten Dateinamen ungerade Zeichen, z. B. Cursorbewegungssequenzen. Versuchen Sie dies, um sicherzustellen, dass:

ls -lq

Es sollte Fragezeichen anstelle von Steuerzeichen anzeigen (dies ist wahrscheinlich die Standardeinstellung, aber möglicherweise nicht).

Dies zeigt teilweise die Art des Problems, das vorhanden sein kann:

touch A C
touch B$(tput cuu1)$'\r'
ls -l
ls -lq
ls -l --show-control-chars    # for systems that have that option and default to -q

Ich würde auch versuchen:

type -a ls
alias ls
declare -f ls
md5sum /bin/ls    # compare to a known-good identical system

um zu sehen, ob ein Alias ​​oder eine Funktion definiert ist oder ob sich eine Binärdatei an einer ungeraden Stelle befindet oder geändert wurde.

Bis auf weiteres angehalten.
quelle
1
+1 guter Einblick. Es ist wichtig zu beachten, dass bei einer lsÄnderung md5summöglicherweise auch das System geändert wurde. Sie benötigen eine bekannte vernünftige Umgebung, um eine endgültige Schlussfolgerung zu ziehen.
Warner
Ich habe festgestellt, dass selbst wenn md5 geändert wurde, um falsche Ergebnisse zu erzielen, wenn Sie Dinge wie 'md5-Datei' ausführen, Sie dennoch gute Ergebnisse erzielen können (wenn das md5-Programm überhaupt funktioniert), indem Sie etwas wie bzip2 <Datei | ausführen md5 und vergleiche das mit dem gleichen Befehl an anderer Stelle.
chris
3

Möglicherweise möchten Sie dieses Volume überprüfen.

Florin Andrei
quelle
13
Das hat sie gesagt.
einstiien
2

Normalerweise mache ich so etwas, wenn ich glaube, dass 'ls' geändert wurde ...

python -c "import os; print os.listdir('.')"

Natürlich Python könnte die C - Bibliothek, der Kern oder das Dateisystem auch modifiziert werden, aber in der Regel ist es nur der Shell - utils.

McJeff
quelle
2
Oder Sie könnten die Dateinamenerweiterung der Shell verwenden, um das Verzeichnis zu lesen - echo * (und wenn Sie alles wollen, echo *. *)
chris
*.*zeigt Ihnen nur Dateien mit Zeichen, gefolgt von einem Punkt gefolgt von Zeichen. Dies ist definitiv nicht alles auf * nix System. Ich bin nicht sicher, ob Echo Ihnen alles in einem Befehl zeigen wird, ich konnte es tunecho * && echo .*
einstiien
4
Wenn Sie genau hinschauen, ist es * (Leerzeichen). *, Nicht *. * Interpunktion ist nicht die Stärke dieses Kommentarsystems ... Und echo ist vollkommen glücklich, so viele Ausdrücke zu erweitern, die durch das "$ IFS" getrennt sind, wie Sie möchten es füttern. Der boolean && ist nicht notwendig, oder wirklich noch viel Sinn machen, da && ein boolean ist und und wird immer funktionieren , weil das Echo Befehl ist immer erfolgreich.
Chris
@chris: mein schlechtes, wirklich schwer zu sehen.
einstiien
2

Sie können mit strace genau untersuchen, was ls tut, und das kann Ihnen sagen, warum es vermieden wird, diesen Dateinamen anzuzeigen.

strace ls -la 653* 2>&1 | less

Schauen Sie sich das an und sehen Sie, was los ist.

strace ls -la 653* 2>&1 | grep ^open

Die Ausgabe sieht folgendermaßen aus:

open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/librt.so.1", O_RDONLY)       = 3
open("/lib/libacl.so.1", O_RDONLY)      = 3
open("/lib/libselinux.so.1", O_RDONLY)  = 3
open("/lib/libc.so.6", O_RDONLY)        = 3
open("/lib/libpthread.so.0", O_RDONLY)  = 3
open("/lib/libattr.so.1", O_RDONLY)     = 3
open("/lib/libdl.so.2", O_RDONLY)       = 3
open("/lib/libsepol.so.1", O_RDONLY)    = 3
open("/etc/selinux/config", O_RDONLY|O_LARGEFILE) = 3
open("/proc/mounts", O_RDONLY|O_LARGEFILE) = 3
open("/selinux/mls", O_RDONLY|O_LARGEFILE) = 3

und wenn du so etwas siehst

open("/var/tmp/.../H@ckl1st", O_RDONLY) = 3

Sei vorsichtig, du wurdest geboren ...

Dies ist kein abschließender Test, aber ein guter Indikator ...

(Wenn Sie Solaris oder andere Betriebssysteme verwenden, müssen Sie möglicherweise ein Fachwerk oder ein ähnliches Dienstprogramm anstelle von strace verwenden.)

(Wenn Sie eine von csh / tcsh abgeleitete Shell verwenden, benötigen Sie wahrscheinlich andere Umleitungsanweisungen.)

chris
quelle
Ich mag das. Das straceDienstprogramm ist wirklich ein Schweizer Taschenmesser. Sie gelangen direkt zur Systemaufrufebene und umgehen einen ganzen Haufen willkürlicher Komplikationen. Es ist eines der ersten Dinge, die ein Systemadministrator tut. einen Cent wert sollte auf eine neu installierte Maschine entleert werden.
McJeff
Ja - die beiden wertvollsten Tools für einen Systemadministrator sind Truss / Strace und TCPDump. Mit diesen können Sie immer unter die Decke schauen, um zu sehen, dass wtf läuft, wenn sich etwas so verhält oder nicht, wie Sie es erwarten.
Chris
2

Schnelles Update, wir mussten den Server aus anderen Gründen ersetzen. Es war das Dateisystem. Jetzt ist alles gut !!! Vielen Dank an alle.

Glücksaxi
quelle
Sie meinen, das Dateisystem war durcheinander und das war nur ein verrücktes Symptom?
Chris
Ja, das war es.
Luckytaxi
Sie hätten wahrscheinlich in einer Bearbeitung stecken bleiben können, um zu sagen, dass die folgende Liste eine Lösung enthält, da sie unter anderen hochgestuften (und für die Fehlerbehebung nützlichen) Antworten vergraben ist.
Bart Silverstrim
0

Die Hack-Theorie ist interessant, aber ich habe eine alternative Theorie. Die Semantik zum Löschen von Unix-Dateien behält die Datei so lange bei, bis alle Prozesse geschlossene Dateihandles geschlossen haben, die darauf zeigen. Möglicherweise hat jemand ein SVN-Checkout / Commit angehalten oder ein Server-Thread ist aufgelegt. Wenn ein Neustart des SVN-Prozesses (oder von Apache) Ihr Problem löst, würde ich hier die Schuld geben.

Vielleicht können Sie den Prozess identifizieren, mit dem diese Datei noch verwendet wird lsof | grep 6535?

jldugger
quelle
ja, lsof hat nichts gezeigt. Das Interessante ist, dass 6535 auch in der Quelle "fehlt". Mein Skript führt eine Hotcopy des ursprünglichen Repos in ein anderes Verzeichnis durch. In diesem Moment stieß ich auf Probleme, weil ich diese bestimmte Datei aus irgendeinem Grund nicht löschen konnte.
Luckytaxi
Eine gelöschte aber offene Datei werden Sie nicht verhindern , das enthält Verzeichnis zu löschen , weil einmal das Verzeichniseintrag gelöscht wird, wird der Verzeichniseintrag nicht vorhanden , so das Verzeichnis wird leer sein. Sie erhalten den Speicherplatz erst aus der Datei zurück, wenn der geöffnete Prozess beendet ist. Das Verzeichnis mit dieser Datei kann jetzt gelöscht werden.
Chris
Ihre alternative Theorie ist interessant. Wenn das Entfernen erfolgreich ist, wird die feste Verbindung sofort entfernt. Der Inode würde wahrscheinlich immer noch die Daten enthalten und einige Dateihandles haben sie möglicherweise im Speicher zwischengespeichert, aber ich glaube nicht, dass dieses Szenario das beschriebene Verhalten erklären könnte. Oder was Chris gesagt hat, heh.
Warner