为什么在运行ls时隐藏此文件?


10

编辑:我完全忘记了这个线程。原来我的硬盘坏了。我们不得不根据其他需求重新部署该服务器,因此我终于解决了替换一个坏磁盘的问题,然后我们又恢复了业务。

几周以来,我一直无法弄清为什么我无法删除这个特定文件。作为超级用户,我可以,但是我的shell脚本以其他用户身份运行。所以我去运行ls -la,它不在那儿。但是,如果我将其作为参数调用,它将显示出来!当然,所有者是root,因此我无法删除。

请注意,缺少6535 ...

[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

现在,如果直接调用它就会显示出来。

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

这很有趣。因此,我抓住了这个问题,因为在我的shell脚本中,由于6535由root拥有,因此无法删除。运行“ rm -rf”后,该文件实际上显示出来。我之前尝试过,但由于无法显示目录不为空,因此无法删除目录。我进去看了一下,果然,文件“ 6535”终于出现了。不知道为什么要这么做。

strace说以下

#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

2
如果您发现此问题,请发布更新。
einstiien

有趣。ls -ab会报告什么?也许文件名中有一些奇数非八进制字符?我想-a仍然会列出它,但我不确定。
egorgry

1
您最近跑过fsck吗?远程可能在文件系统上发生故障。
Zoredache

明天我将不得不再次进行测试,只剩下一天了。
luckytaxi 2010年

Answers:


7

有点令人担忧。ls通过与已知良好的文件进行比较,我将确认您的文件没有被修改。您可以使用发行版的打包工具在隔离的系统上验证文件。


+1:ls -al应该显示所有内容。如果没有,那地方就出问题了。
Satanicpuppy

2
这很可能是ls已被修改为隐藏特定PID,可能是6535.
MikeyB

不,不,不……
luckytaxi 2010年

6

有时,文件名中会出现奇数字符,例如光标移动顺序。尝试执行以下操作以确保:

ls -lq

它应该显示问号而不是控制字符(这可能是默认值,但可能不是)。

这部分显示了可能存在的问题类型:

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

我也会尝试:

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

查看是否已定义别名或函数,或者查看二进制文件是否在奇数位或已被修改。


1
+1洞察力。重要的是要注意,如果ls进行了修改,md5sum则系统上的操作系统也可能也已被修改。您需要一个已知的合理环境来进行验证以得出明确的结论。
华纳2010年

我发现,即使执行md5文件之类的操作,即使md5已更改为产生假结果,通过执行bzip2 <file | MD5和比较的是相同的命令别处。
克里斯


2

如果我相信'ls'已被修改,我通常会这样做。

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

当然,可以修改Python,C库,内核或文件系统,但通常只是shell utils。


2
或者,您可以使用Shell的文件名扩展来读取目录-echo *(如果需要,请使用echo *。*)
chris

*.*只会向您显示包含字符,后跟点,后跟字符的文件。这绝对不是* nix系统上的所有内容。我不确定echo是否会在一个命令中向您显示所有内容,但我做到了echo * && echo .*
einstiien 2010年

4
如果仔细观察,它是*(空格)。*,而不是*。*标点符号不是此注释系统的强项...而且,echo非常乐意扩展尽可能多的由“ $ IFS”分隔的表达式你在乎喂。布尔值&&是不必要的,或者甚至说不通,因为&&是布尔值并且因为echo命令总是成功而将一直有效。
克里斯

@chris:我的糟糕,真的很难看到。
einstiien

2

您可以使用strace来确切地查看ls在做什么,这也许可以告诉您为什么它避免显示该文件名。

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

通过那看,看看发生了什么。

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

输出将如下所示:

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

如果您看到类似

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

小心,您已经拥有了0wn ...

这不是一个确定的测试,但它是一个很好的指标...

(如果使用的是solaris或其他操作系统,则可能需要使用truss或其他类似的实用程序代替strace)

(如果您使用的是csh / tcsh派生的shell,则可能需要其他重定向语句)


我喜欢这个。该strace实用程序确实是瑞士军刀。您可以直接进入系统调用级别,并绕开一大堆任意复杂的问题。这是任何系统管理员的首要任务之一。值得一毛钱应该倾倒在新安装的计算机上。
McJeff 2010年

是的-对于系统管理员来说,两个最有价值的工具是truss / strace和tcpdump。有了这些,您可以在某些情况下以预期的方式查看wtf的运行情况。
克里斯

2

快速更新,由于其他原因,我们不得不更换服务器。那是文件系统。现在一切都很好!!!谢谢大家。


您的意思是文件系统搞砸了,这只是一个古怪的症状?
克里斯

是的,就是这样。
luckytaxi 2010年

您可能会一直在编辑中说下面的列表中有一个解决方案,因为该解决方案被埋在其他建议的答案(对解决问题很有用)的下方。
巴特·

0

哈克理论很有趣,但我有另一种理论。Unix文件删除语义将保留文件,直到所有进程关闭指向它的打开文件句柄为止。也许有人暂停了SVN检出/提交,或者服务器线程挂起。如果重新启动SVN进程(或Apache)解决了您的问题,这就是我的责任。

也许您可以确定仍使用此文件的过程lsof | grep 6535


是的,lsof没有显示任何内容。有趣的是,6535在源中也“缺失”。我的脚本将原始存储库热复制到另一个目录。那时,由于某种原因,我遇到了无法删除此特定文件的问题。
luckytaxi 2010年

删除但打开的文件不会阻止您删除包含的目录,因为一旦删除该目录条目,该目录条目将不存在,因此该目录将为空。在打开它的进程被杀死之前,您不会从文件中获取空间,但是现在可以删除包含该文件的目录。
克里斯

您的替代理论很有趣。如果删除成功,则将立即删除硬链接。索引节点可能仍会包含数据,某些文件句柄可能会将其缓存在内存中,但是我不认为这种情况可以解释所描述的行为。还是克里斯说的,嘿。
华纳
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.