Làm thế nào để tạo một tệp có tên giống như một đối số dòng lệnh?


29

Tôi đã tự hỏi làm thế nào để tạo một tệp có tên là cờ, ví dụ, nếu tôi muốn tạo một thư mục có tên -a, những lệnh nào sẽ thực hiện thủ thuật?

Tôi đã thử mkdir '-a', mkdir \-avà không làm việc. Tôi đang dùng Ubuntu.


13
Các câu trả lời ở đây đều rất hay, nhưng tôi không thể nghĩ ra lý do không phải là troll để muốn làm điều này ...
evilsoup

@evilsoup Một số người thích tiền tố thư mục để họ dán ở đầu trong một danh sách được sắp xếp chữ và số. Nhưng đó là lý do duy nhất tôi có thể nghĩ ra, thành thật mà nói.
slhck

@slhck Tôi biết ít nhất một khóa học chỉnh sửa video nơi họ khuyến khích sinh viên nối các khoảng trống vào thư mục dự án của họ để họ sẽ xuất hiện ở đầu trên iMac chung. Điều này thật xấu xí và dẫn đến sự leo thang vui nhộn, nhưng ít nhất nó sẽ không có khả năng phá vỡ hệ thống ...
evilsoup

3
Chủ yếu đây là ở đây cho lợi ích học tập.
MYV

5
Truyện tranh bắt buộc: beesbuzz.biz/d/20110224.php
fluffy

Câu trả lời:


49

Gọi lệnh như vậy:

mkdir -- -a

Điều --đó có nghĩa là các tùy chọn kết thúc sau đó, do đó, -ađược hiểu theo nghĩa đen và không phải là một tùy chọn mkdir. Bạn sẽ tìm thấy cú pháp này không chỉ trong mkdir, mà bất kỳ tiện ích tuân thủ POSIX nào ngoại trừ echotest. Từ đặc điểm kỹ thuật :

Đối số - nên được chấp nhận như là một dấu phân cách chỉ ra sự kết thúc của các tùy chọn. Bất kỳ đối số nào sau đây phải được coi là toán hạng, ngay cả khi chúng bắt đầu bằng ký tự '-'. Không nên sử dụng đối số - làm tùy chọn hoặc toán hạng.

Sử dụng --như một biện pháp bảo vệ được khuyến nghị cho hầu hết mọi hành động khi bạn xử lý tên tệp và muốn đảm bảo rằng chúng không vi phạm lệnh, ví dụ: khi di chuyển tệp trong một vòng lặp bạn có thể muốn gọi như sau, để tệp có tên là -i' t (in?) được phân tích chính xác như một tùy chọn:

mv -- "$f" new-"$f"

Nhược điểm của phương pháp này là chính xác là nó chấm dứt xử lý tùy chọn. Đối với một ví dụ mkdir đơn giản, điều đó làm việc kỳ diệu; nếu bạn thực sự cần một tùy chọn để theo tên tệp trên dòng lệnh, nó sẽ không hoạt động.
CVn

1
Tất nhiên là có một nhược điểm của tất cả mọi thứ. Trong trường hợp bạn xử lý các tên tệp xen kẽ với các tùy chọn, giải pháp của Amos sẽ là giải pháp thay thế lành mạnh duy nhất tôi có thể nghĩ ra, nhưng nó thực sự phụ thuộc vào cách công cụ phân tích các tùy chọn.
slhck

1
Vì OP nói về việc tạo một tệp có tên "giống như một đối số dòng lệnh" (giả sử có nghĩa là một tên bắt đầu bằng dấu gạch nối), tôi không nghĩ đó là một giả định hoàn toàn vô lý. Lấy cc -o -myfile -Wall -myfile.cmột ví dụ chỉ hơi khó khăn. Bất kỳ trình soạn thảo nào có giá trị muối của nó sẽ có thể lưu vào một tệp có tên -myfile.cnếu bạn yêu cầu nó, nhưng trình biên dịch C có thể sẽ không làm những gì bạn muốn khi đưa ra một danh sách các tùy chọn như vậy.
một CVn

1
@Maksim Ví dụ các lệnh yêu cầu tùy chọn đặt tên tệp đầu vào hoặc đầu ra, như cclệnh Michael đưa ra ở trên, có -otùy chọn chỉ định tệp đầu ra.
slhck

1
Ví dụ vòng lặp là lý do tại sao bạn nên luôn luôn sử dụng một cái gì đó giống như for f in ./*; do...hơnfor f in *; do...
evilsoup

21

Cách đơn giản nhất nên làm việc với bất kỳ chương trình hợp lý nào là sử dụng tên đường dẫn tương đối phía trước -, ví dụ: mkdir ./-asẽ tạo một thư mục được gọi -atrong thư mục làm việc hiện tại.

Ví dụ phổ biến nhất về việc sử dụng "mẹo" này là khi bạn muốn xóa một tệp bắt đầu bằng dấu gạch ngang, vì vậy bạn có thể làm rm ./-a.


3
Tất nhiên đó chỉ là mẹo nếu bạn làm việc với các đường dẫn tệp chứ không phải bất kỳ tùy chọn dòng lệnh tùy ý nào được phân tích cú pháp dưới dạng chuỗi. Nhưng nếu không, tiền tố ./luôn là một ý tưởng hay, hãy tưởng tượng bạn đã tạo một tệp được gọi -rfvà sau đó bạn đã gọi rm *.
slhck

1
@slhck Để nhiều người có thể nhìn một trò đùa. Nhưng tôi đã thấy đủ trường hợp loại thứ này bị xóa sổ (một phần) của một máy chủ. Bạn không thể cảnh báo mọi người đủ về sự nguy hiểm của các tệp bắt đầu bằng dấu gạch ngang. Một nơi tôi từng làm việc thậm chí có quy tắc chính thức: Không bao giờ tạo tệp có tên bắt đầu bằng "-f" hoặc "-r".
Tonny

1
Đây phải là câu trả lời: đó là cách di động duy nhất ( --không được hiểu bởi mọi lệnh, chỉ một vài)
Olivier Dulac

@OlivierDulac Tôi nghĩ rằng đó --là một điều bash, vì vậy nó nên hoạt động cho tất cả các chương trình?
gsingh2011

@ gsingh2011 không, mã quyết định xem "-" có được coi là điểm đánh dấu "kết thúc cờ" trong ứng dụng hay không và tùy thuộc vào từng ứng dụng để quyết định xem nó có xử lý theo cách đó hay không.
Amos Shapira

4

Lý do tại sao mkdir '-a', hoặc mkdir \-akhông hoạt động là vì cả hai phương pháp này (sử dụng dấu ngoặc kép hoặc dấu gạch chéo ngược) được sử dụng để ngăn vỏ của bạn (có thể bash) không mang lại cho chúng bất kỳ ý nghĩa đặc biệt nào. Vì -adù sao nó cũng không có ý nghĩa gì đặc biệt đối với vỏ, nên những thứ này không ảnh hưởng đến cách nó được truyền lại mkdir.

Theo như mkdircó liên quan, nó nhận được một danh sách các đối số từ shell và nó không thể cho biết bạn có đặt chúng trong dấu ngoặc kép hay không, hoặc liệu có dấu gạch chéo ngược hay không. Nó chỉ thấy một đối số -a. Đó là lý do tại sao bạn cần --như được giải thích trong các câu trả lời khác.


-3

Ngoài câu trả lời từ "slhck", có một mẹo khác đôi khi hoạt động:

Đặt tên tệp trong câu hỏi trong vòng 2 bộ qoutes khác nhau như "'-a'"hoặc '"-a"'.

Việc này có hoạt động hay không phụ thuộc vào chương trình, nhưng đây là biện pháp cuối cùng nếu chương trình không hỗ trợ --tính năng POSIX .
Phương pháp POSIX luôn được ưa thích vì nó đáng tin cậy 100%.


"Phương pháp POSIX luôn được ưa thích vì nó đáng tin cậy 100%." Sử dụng --để chấm dứt xử lý tùy chọn cũng cho rằng bạn không cần bất kỳ tùy chọn nào để theo tên tệp, điều này không phải lúc nào cũng đúng.
CVn

@ MichaelKjorling Tất nhiên ... Nhưng tôi loại giả định đó sẽ là hiển nhiên.
Tonny

4
Điều này sẽ tạo một tệp có tên '-a'hoặc "-a", ít nhất là trên các hệ thống loại BSD
nohillside

4
Bạn có thể trích dẫn một hệ điều hành / shell nơi nó không hoạt động?
nohillside

1
nếu nó hoạt động, có vẻ như bạn sẽ gặp vấn đề khá nghiêm trọng khi xử lý các tệp có tên được bao quanh bởi dấu ngoặc kép.
muhmuhten
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.