Ai giao dịch với ngôi sao * trong tiếng vang *


15

Ai giao dịch (phiên dịch) * trong

echo *

Liệu tiếng vang nhìn thấy ngôi sao hoặc vỏ có quan tâm đến nó và trả về một danh sách tên tệp ..

Thế còn

cp temp temp*

14
Nó thay đổi. Shell Unix hay Windows shell?
dùng1686

@grawity shell Unix. Xin lỗi tôi đã không đề cập đến điều đó.
faressoft

Đối với Unix, các câu trả lời dưới đây là chính xác. (Trên Windows, nó được thực hiện bởi các chương trình riêng lẻ - mặc dù thường là thư viện thời gian chạy tự động trước main ().)
user1686

Câu trả lời:


24

bash (hoặc bất cứ thứ gì bạn sử dụng làm shell), là điều đầu tiên để đọc bất kỳ đầu vào nào và sẽ bắt đầu diễn giải các ký tự đặc biệt như ?*. *được mở rộng thành bất kỳ trận đấu nào trong CWD , điều đó có nghĩa là dấu hoa thị được thay thế bằng các trận đấu đã nói.

Trong hầu hết các trường hợp, điều này khá khó khăn về phía trước, nhưng đôi khi có thể dẫn đến một số trường hợp khó hiểu.

Hãy xem xét những điều sau đây. Một thư mục có nội dung này:

  • kiểm tra (tập tin thường xuyên)
  • test1 (thư mục)
  • test2 (thư mục)
  • test3 (thư mục)

Nếu sau đó bạn gõ mv *một cái gì đó có vẻ kỳ lạ xảy ra: test3có, nhưng phần còn lại đã biến mất. Mặc dù kỳ lạ lúc đầu, nó có ý nghĩa một khi bạn hiểu những gì bash thực sự chuyển đến mv. Do dấu hoa thị, bash diễn giải mv *mv test test1 test2 test3và khi mv có được danh sách đó, nó sẽ cho rằng tranh luận cuối cùng là đích đến, đó là nơi mà tất cả các tệp sẽ được di chuyển.

Đối với các lệnh bạn đã liệt kê:

  • echo *có chức năng như một người nghèo-mans ls. Shell sẽ mở rộng dấu hoa thị thành bất cứ thứ gì có trong thư mục đó, và như tôi chắc chắn bạn đã biết, theo echonghĩa đen sẽ chỉ lặp lại bất cứ thứ gì bash truyền cho nó như là những tranh luận.
  • cp temp temp*sẽ hoạt động hơi giống mvlệnh tôi đã mô tả ở trên, trừ khi chỉ có một thư mục có tên temp, trong trường hợp đó tên nguồn và tên đích là như nhau, tức là nó sẽ không làm gì cả.

8
Không có gì "nghèo" về việc sử dụng *thay vì ls. Ví dụ, for f in *; donhiều hơn đáng tin cậy hơn for f in $(ls)nếu một tên tập tin chứa khoảng trắng hoặc ký tự glob. (Tuy nhiên, nó sẽ thất bại nếu không có tệp nào trong CWD, vì vậy bạn cần phải kiểm tra trường hợp đó.)
rici

1
@rici Đó là những gì shopt nullglobdành cho.
một CVn

3
Đối với echo *, thủ thuật đó có thể giúp bạn tiết kiệm trong một số trường hợp.
một CVn

2
Chiming in với: các tệp được đặt trước "-" trong các thư mục tùy ý kích hoạt các chuyển đổi không mong muốn. Loại bỏ chúng không có nhiều niềm vui cho đến khi bạn nhận ra rằng rm ./-stoolfile hoạt động.
ǝɲǝɲbρɯͽ

1
@ bρɯͽ Tôi nhận thấy khi tôi cần xóa nội dung của thư mục chứa các tệp có tên tệp đại diện cho các vị trí trong một hệ tọa độ, từ -1024x-1024 đến 1024x1024. Đó là khi tôi mới biết về việc trốn thoát.
Jarmund

5

Như đã nêu, shell mở rộng *để echonhận dưới dạng đối số bất cứ thứ gì shell tìm thấy trong thư mục hiện tại. Tuy nhiên, lưu ý rằng nếu việc mở rộng dẫn đến không có gì, tức là trong trường hợp đó nếu thư mục không chứa các tệp không bị ẩn, thì phần *còn lại không thay đổi và được chuyển như là lệnh được gọi (trừ khi các tùy chọn không chuẩn được sử dụng với một số shell như bash.) echo *sau đó sẽ không cư xử như một người nghèo vì người lstrước sẽ không in gì trong khi người sau sẽ in *.

Tương tự, cp /tmp/temp temp*sẽ tạo một tệp có tên temp*trong thư mục hiện tại nếu chưa có ít nhất một tệp có tên bắt đầu bằng temp.

Cuối cùng, nếu bạn muốn *thông qua không thay đổi bất kể trường hợp nào, bạn có thể bảo vệ nó khỏi sự mở rộng bằng cách sử dụng dấu ngoặc đơn '*', dấu ngoặc kép "*"hoặc dấu gạch chéo ngược \*.


4

Trong Bash, vỏ đối phó với nó. Bạn thấy rằng nếu bạn thậm chí thử *mà không có tiếng vang

Lưu ý dựa trên một số nhận xét, tôi sẽ đề xuất khi chạy * ENTER, để tạo thư mục và sử dụng lệnh cảm ứng để tạo một số tệp và đảm bảo không ai trong số chúng, hoặc ít nhất là đảm bảo rằng đầu tiên theo thứ tự bảng chữ cái, không phải là tên của bất kỳ tập lệnh hoặc lệnh nào trong đường dẫn.

$ *
bash: a: command not found

$ echo *
a a.aa a.ab a.b a.htm a.tx

Vì vậy, ls *là một chút của một cliche

Trong Windows, *được xử lý bởi lệnh, vì vậy dir *.*không phải là một sáo ngữ.

Lưu ý- Thấy một số bình luận, tôi sẽ thêm, có rủi ro khi chạy * sau đó ENTER. Nếu bạn có một tệp có tên rm đầu tiên trong danh sách thư mục, thì thật nguy hiểm vì mọi thứ sau đó sẽ bị xóa. Ngoài ra, và điều này ít có khả năng hơn, nếu tệp đầu tiên trong danh sách thư mục là tên của một tập lệnh trong đường dẫn, thì nó sẽ chạy nó.


4
Lưu ý có thể có một tập tin có tên rm, tất nhiên.
Volker Siegel

1
... và một cái khác gọi là -rf
ǝɲǝɲbρɯͽ

1
@ bρɯͽ bạn có thể có một tập tin có tên tệp là -rfgì không? Tôi đã thử touch -rftouch \-rfnó không tạo ra nó.
barlop

@barlop Tôi đã nhận xét ở trên; gui (như gedit) xử lý chúng tốt, nhưng vì shell (ít nhất là bash) chuyển cái này qua nó yêu cầu ./ ở phía trước. Nếu bạn vô tình tạo một tập tin như vậy, rm sẽ cố gắng gợi ý, nhưng nếu không: Tôi hy vọng điều này chỉ bao giờ kết thúc trong một thư mục tạm thời với trẻ em dùng một lần.
ǝɲǝɲbρɯͽ

@ bρɯͽ Tôi không hiểu ý của bạn là gì, tôi đang hỏi làm thế nào bạn có thể tạo một tệp có tên -rf? (Tôi hiểu sự nguy hiểm của một tập tin gọi là rm và một tập tin gọi -rf, và các vấn đề về gõ * và đẩy nhập vào trong một thư mục quan trọng, tôi không có ý định làm điều đó)
barlop

-1

Shell thực hiện một số mở rộng trước khi các đối số được trao cho lệnh.

Xem thêm https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion

Không dành riêng cho bash, hãy xem http://pub.opengroup.org/onlinepub/9699919799/utilities/V3_chap02.html#tag_18_01


Về mặt kỹ thuật những gì bạn đang viết là chính xác, nhưng không có các liên kết, câu trả lời này thực sự không làm gì để trả lời câu hỏi. Xem xét kết hợp các chi tiết có liên quan.
một CVn

@ MichaelKjorling Tôi đồng ý với điều này về các liên kết, nhưng OP chỉ đơn giản hỏi liệu trình bao hay lệnh tự xử lý các đối số. Câu trả lời của Glenn chỉ đơn giản nói rằng cái vỏ xử lý chúng, vì vậy đó là một câu trả lời chấp nhận được cho câu hỏi.
slhck

@slhck Đó là lý do tại sao tôi không gắn cờ là NAA: có gì đó còn lại để giải quyết câu hỏi sau khi tước liên kết. Điều đó không có nghĩa đây là một câu trả lời tốt theo ý kiến ​​của tôi . (Bây giờ tôi thấy rằng bình luận ban đầu của tôi có thể được hiểu hình thức khác; vì điều đó, tôi xin lỗi, nhưng tôi vẫn nghĩ rằng nó có đủ giá trị để lại nó ở đâu.)
một CVN

@ MichaelKjorling Đồng ý. Tôi chỉ để lại nhận xét cho những người đã (và sẽ) gắn cờ nó là NAA.
slhck
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.