Các a*
và *a*
cú pháp được thực hiện bởi vỏ, không phải do ls
lệnh.
Khi bạn gõ
ls a*
tại dấu nhắc shell của bạn, shell sẽ mở rộng a*
thành một danh sách tất cả các tệp trong thư mục hiện tại có tên bắt đầu bằng a
. Ví dụ, nó có thể mở rộng a*
thành chuỗi a1 a2 a3
và chuyển chúng thành đối số ls
. Bản ls
thân lệnh không bao giờ nhìn thấy *
nhân vật; nó chỉ nhìn thấy ba đối số a1
, a2
và a3
.
Đối với mục đích mở rộng ký tự đại diện, "tệp" đề cập đến tất cả các thực thể trong thư mục hiện tại. Ví dụ: a1
có thể là một tệp bình thường, a2
có thể là một thư mục và a3
có thể là một liên kết tượng trưng. Tất cả chúng đều có các mục nhập thư mục và việc mở rộng ký tự đại diện của shell không quan tâm loại thực thể mà các mục đó đề cập đến.
Thực tế tất cả các shell bạn có khả năng chạy ngang qua (bash, sh, ksh, zsh, csh, tcsh, ...) thực hiện các ký tự đại diện. Các chi tiết có thể khác nhau, nhưng cú pháp cơ bản của việc *
ghép 0 hoặc nhiều ký tự và ?
khớp với bất kỳ ký tự đơn nào là phù hợp một cách hợp lý.
Đối với bash nói riêng, điều này được ghi lại trong phần "Mở rộng tên tệp" trong hướng dẫn sử dụng bash; chạy info bash
và tìm kiếm "Mở rộng tên tệp", hoặc xem tại đây .
Thực tế là điều này được thực hiện bởi shell chứ không phải bởi các lệnh riêng lẻ, có một số hậu quả thú vị (và đôi khi đáng ngạc nhiên). Điều tốt nhất về nó là việc xử lý ký tự đại diện phù hợp với (rất gần) tất cả các lệnh; nếu shell không làm điều này, chắc chắn một số lệnh sẽ không làm phiền và những lệnh khác sẽ làm điều đó theo những cách khác nhau mà tác giả nghĩ là "tốt hơn". (Tôi nghĩ shell lệnh Windows có vấn đề này, nhưng tôi không đủ quen thuộc với nó để bình luận thêm.)
Mặt khác, thật khó để viết một lệnh để đổi tên nhiều tệp. Nếu bạn viết:
mv *.log *.log.bak
nó có thể sẽ thất bại, vì *.log.bak
được mở rộng dựa trên các tệp đã tồn tại trong thư mục hiện tại. Có những lệnh thực hiện loại điều này, nhưng chúng phải sử dụng cú pháp của riêng chúng để xác định cách các tệp được đổi tên. Một số lệnh (chẳng hạn như find
) có thể thực hiện mở rộng ký tự đại diện của riêng chúng; bạn phải trích dẫn các đối số để ngăn chặn sự mở rộng của shell:
find . -name '*.txt' -print
Mở rộng ký tự đại diện của shell hoàn toàn dựa trên cú pháp của đối số dòng lệnh và tập hợp các tệp hiện có. Nó không thể bị ảnh hưởng bởi ý nghĩa của lệnh. Ví dụ: nếu bạn muốn di chuyển tất cả .log
các tệp lên thư mục mẹ, bạn có thể nhập:
mv *.log ..
Nếu bạn quên ..
:
mv *.log
và có hai .log
tệp trong thư mục hiện tại, nó sẽ mở rộng thành:
mv one.log two.log
Nó sẽ đổi tên one.log
và clobber two.log
.
EDIT : Và sau 52 lần nâng cấp, chấp nhận và huy hiệu Guru, có lẽ tôi thực sự nên trả lời câu hỏi trong tiêu đề.
Các -d
hoặc --directory
tùy chọn để ls
không nói với nó để chỉ liệt kê các thư mục. Nó bảo nó liệt kê các thư mục giống như chính chúng, không phải nội dung của chúng. Nếu bạn đặt tên thư mục làm đối số ls
, theo mặc định, nó sẽ liệt kê nội dung của thư mục, vì đó thường là những gì bạn quan tâm. -d
Tùy chọn này chỉ liệt kê danh sách thư mục đó. Điều này có thể đặc biệt hữu ích khi kết hợp với ký tự đại diện. Nếu bạn gõ:
ls -l a*
ls
sẽ cung cấp cho bạn một danh sách dài của mỗi tệp có tên bắt đầu a
và nội dung của mỗi thư mục có tên bắt đầu a
. Nếu bạn chỉ muốn một danh sách các tệp và thư mục, mỗi dòng cho một dòng, bạn có thể sử dụng:
ls -ld a*
tương đương với:
ls -l -d a*
Hãy nhớ lại rằng ls
lệnh không bao giờ nhìn thấy *
nhân vật.
Về phần tài liệu này, man ls
sẽ hiển thị cho bạn tài liệu về ls
lệnh trên bất kỳ hệ thống nào giống Unix. Trên hầu hết các hệ thống dựa trên Linux, ls
lệnh là một phần của gói GNU coreutils; nếu bạn có info
lệnh, info ls
hoặc info coreutils ls
sẽ cung cấp cho bạn tài liệu chính xác và toàn diện hơn. Các hệ thống khác, chẳng hạn như MacOS, có thể sử dụng các phiên bản khác nhau của ls
lệnh và có thể không có info
lệnh; Đối với những hệ thống, sử dụng man ls
. Và ls --help
sẽ hiển thị một thông báo sử dụng tương đối ngắn (117 dòng trên hệ thống của tôi) nếu bạn đang sử dụng triển khai GNU coreutils.
Và có, ngay cả các chuyên gia cần phải tham khảo tài liệu bây giờ và sau đó. Xem thêm trò đùa kinh điển này .