Tại sao tập tin này bị ẩn khi bạn chạy ls?


10

EDIT: Tôi hoàn toàn quên mất chủ đề này. Hóa ra tôi đã có một đĩa cứng xấu. Chúng tôi đã phải triển khai lại máy chủ này cho các nhu cầu khác vì vậy cuối cùng tôi đã tìm cách thay thế một đĩa xấu và chúng tôi đã hoạt động trở lại.

Trong vài tuần nay tôi không thể hiểu tại sao tôi không thể xóa một tập tin cụ thể này. Là root tôi có thể, nhưng kịch bản shell của tôi chạy như một người dùng khác. Vì vậy, tôi đi chạy ls -la và nó không ở đó. Tuy nhiên, nếu tôi gọi nó là một tham số, nó sẽ hiển thị! Chắc chắn, chủ sở hữu là root, do đó tôi không thể xóa.

Lưu ý, 6535 bị thiếu ...

[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

Bây giờ nó xuất hiện nếu bạn gọi nó trực tiếp.

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

Đây là một cái gì đó thú vị. Vì vậy, tôi đã bắt gặp vấn đề này bởi vì trong tập lệnh shell của tôi, nó sẽ không xóa được vì 6535 thuộc sở hữu của root. Các tập tin thực sự xuất hiện sau khi tôi chạy "rm -rf." Tôi đã thử nó trước đó và nó không thể xóa thư mục vì nó nói với tôi rằng thư mục không trống. Tôi đi vào và nhìn và chắc chắn, tập tin "6535" cuối cùng cũng xuất hiện. Không biết tại sao nó lại làm điều này.

strace nói như sau

#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
Nếu bạn tìm ra điều này xin vui lòng gửi một bản cập nhật.
einstiien

Hấp dẫn. những gì được báo cáo với ls -ab? Có lẽ một số ký tự không bát phân lẻ có trong tên tệp? Tôi sẽ nghĩ - dù sao tôi cũng sẽ liệt kê nó nhưng tôi không chắc.
egorgry

1
Bạn đã chạy một fsck gần đây? Nó có thể từ xa có thể một cái gì đó bị phá vỡ trên hệ thống tập tin.
Zoredache

Tôi sẽ phải kiểm tra lại vào ngày mai, để lại trong ngày.
luckytaxi

Câu trả lời:


7

Đó là một chút lo lắng. Tôi xác minh rằng lstệp của bạn không bị sửa đổi bằng cách so sánh với một tệp tốt đã biết. Bạn có thể sử dụng các công cụ gói phân phối của mình để xác minh tệp trên một hệ thống bị cô lập.


+1: ls -al sẽ hiển thị mọi thứ. Nếu nó không có vấn đề ở đâu đó.
Satanicpuppy

2
Hoàn toàn có thể lsđã được sửa đổi để ẩn một PID cụ thể, có thể là 6535.
MikeyB

Không ... không có gì ...
luckytaxi

6

Đôi khi tên tệp nhận được các ký tự kỳ lạ trong đó, chẳng hạn như chuỗi chuyển động con trỏ. Hãy thử điều này để đảm bảo:

ls -lq

Nó sẽ hiển thị các dấu hỏi thay vì các ký tự điều khiển (có thể là mặc định, nhưng có thể không phải vậy).

Điều này một phần thể hiện loại vấn đề có thể có:

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

Tôi cũng sẽ thử:

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

để xem nếu một bí danh hoặc chức năng được xác định hoặc để xem nếu một nhị phân ở một vị trí kỳ lạ hoặc đã được sửa đổi.


1
Cái nhìn sâu sắc tốt. Điều quan trọng cần lưu ý là nếu lsđược sửa đổi, md5sumhệ thống cũng có khả năng bị sửa đổi. Bạn cần một môi trường lành mạnh đã biết để xác minh để đi đến kết luận dứt khoát.
Warner

Tôi đã thấy rằng ngay cả khi md5 đã bị thay đổi để tạo ra kết quả không có thật nếu bạn làm những việc như 'tập tin md5', bạn vẫn có thể nhận được kết quả tốt (nếu chương trình md5 hoạt động hoàn toàn) bằng cách làm một cái gì đó như bzip2 <file | md5 và so sánh rằng với cùng lệnh ở nơi khác.
chris


2

Tôi thường làm một cái gì đó như thế này nếu tôi tin rằng 'ls' đã được sửa đổi ...

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

Tất nhiên Python, Thư viện C, kernel hoặc hệ thống tệp cũng có thể được sửa đổi, nhưng thông thường nó chỉ là các tiện ích shell.


2
Hoặc, bạn có thể sử dụng mở rộng tên tệp của shell để đọc thư mục - echo * (và nếu bạn muốn mọi thứ, echo *. *)
chris

*.*sẽ chỉ hiển thị cho bạn các tệp có ký tự được theo sau bởi dấu chấm theo sau là ký tự. Đây chắc chắn không phải là tất cả mọi thứ trên hệ thống * nix. Tôi không chắc chắn tiếng vang sẽ cho bạn thấy tất cả mọi thứ trong một lệnh, tôi đã có thể làm điều đóecho * && echo .*
einstiien

4
Nếu bạn nhìn kỹ, đó là * (dấu cách). bạn quan tâm để nuôi nó Boolean && là không cần thiết, hoặc thực sự thậm chí có ý nghĩa nhiều, vì && là một boolean và sẽ luôn luôn làm việc vì lệnh echo luôn là thành công.
Chris

@chris: xấu của tôi, thực sự rất khó để thấy điều đó.
einstiien

2

Bạn có thể xem xét chính xác những gì ls đang làm bằng cách sử dụng strace và điều đó có thể cho bạn biết lý do tại sao nó tránh hiển thị tên tệp đó.

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

nhìn qua đó và xem những gì đang xảy ra

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

Đầu ra sẽ như thế này:

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

và nếu bạn thấy một cái gì đó như

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

hãy cẩn thận, bạn đã bị 0wned ...

Đây không phải là một thử nghiệm kết luận, nhưng nó là một chỉ số tốt ...

(nếu bạn đang sử dụng solaris hoặc các HĐH khác, bạn có thể cần sử dụng giàn hoặc một số tiện ích tương tự khác thay vì strace)

(nếu bạn đang sử dụng lớp vỏ có nguồn gốc csh / tcsh, bạn có thể sẽ cần các câu lệnh chuyển hướng khác nhau)


Tôi thích điều này. Các stracetiện ích thực sự là một con dao quân đội Thụy Sĩ. Bạn có quyền truy cập cấp độ hệ thống và bỏ qua cả đống biến chứng tùy ý. Đó là một trong những điều đầu tiên bất kỳ quản trị hệ thống. đáng giá một xu nên đổ vào một máy mới được cài đặt.
McJeff

Vâng - hai công cụ có giá trị nhất cho quản trị viên hệ thống là truss / strace và tcpdump. Với những điều này, bạn luôn có thể nhìn vào trang bìa để thấy wtf đang diễn ra khi có điều gì đó hoặc không hành xử theo cách bạn mong đợi.
chris

2

Cập nhật nhanh, chúng tôi đã phải thay thế máy chủ vì lý do khác. Đó là hệ thống tập tin. Bây giờ tất cả đều ổn !!! Cảm ơn mọi người.


Bạn có nghĩa là hệ thống tập tin đã bị hỏng và đây chỉ là một triệu chứng lập dị?
chris

vâng đó là nó.
luckytaxi

Bạn có thể đã bị mắc kẹt trong một chỉnh sửa để nói rằng có một giải pháp trong danh sách bên dưới, vì nó đã bị chôn vùi bên dưới các câu trả lời nâng cao khác (và hữu ích để khắc phục sự cố).
Bart Silverstrim

0

Lý thuyết hack rất thú vị, nhưng tôi có một lý thuyết thay thế. Ngữ nghĩa xóa tệp Unix sẽ giữ tệp xung quanh cho đến khi tất cả các quy trình đã đóng xử lý tệp mở đóng vào nó. Có lẽ ai đó đã tạm dừng thanh toán / cam kết SVN hoặc luồng máy chủ bị treo. Nếu khởi động lại quy trình SVN (hoặc Apache) giải quyết vấn đề của bạn, đây là nơi tôi sẽ đổ lỗi.

Có lẽ bạn có thể xác định quá trình vẫn sử dụng tập tin này với lsof | grep 6535?


yea lsof đã không hiển thị bất cứ điều gì. Điều thú vị là, 6535 cũng "mất tích" trong nguồn. Kịch bản của tôi thực hiện một bản sao nóng của repo gốc sang thư mục khác. Đó là khi tôi gặp vấn đề với việc không thể xóa tệp cụ thể này vì một số lý do.
luckytaxi

Một tệp bị xóa nhưng mở sẽ không ngăn bạn xóa thư mục chứa vì một khi mục nhập thư mục đó bị xóa, mục nhập thư mục sẽ không tồn tại nên thư mục sẽ trống. Bạn sẽ không lấy lại được khoảng trống từ tệp cho đến khi quá trình mở nó bị hủy, nhưng thư mục có tệp đó bây giờ có thể bị xóa.
chris

Lý thuyết thay thế của bạn là thú vị. Việc xóa, nếu thành công, sẽ ngay lập tức xóa liên kết cứng. Inode có khả năng vẫn chứa dữ liệu và một số xử lý tệp có thể lưu vào bộ nhớ trong bộ nhớ, nhưng tôi không tin kịch bản này có thể giải thích hành vi được mô tả. Hoặc, những gì chris nói, heh.
Warner
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.