Jak utworzyć plik o nazwie takiej jak argument wiersza poleceń?

29

Zastanawiałem się, jak utworzyć plik o nazwie jako flaga, np. Jeśli chciałbym utworzyć folder o nazwie -a, jakie polecenia by to załatwiły?

Próbowałem mkdir '-a', mkdir \-ai nie działało. Jestem na Ubuntu.

MOJA V
źródło
13
Wszystkie odpowiedzi tutaj są świetne, ale nie mogę wymyślić innego powodu, aby chcieć to zrobić ...
evilsoup
@evilsoup Niektóre osoby lubią prefiksować foldery, aby pozostały na górze listy uporządkowanej alfanumerycznie. Ale to jedyny powód, dla którego mogę wymyślić, szczerze mówiąc.
slhck
@slhck Znam co najmniej jeden kurs edycji wideo, w którym zachęcają studentów do dodawania pustych miejsc do katalogów swoich projektów, aby pojawili się u góry na wspólnych komputerach iMac. To było brzydkie i doprowadziło do zabawnej eskalacji, ale przynajmniej nie byłoby potencjalnie łamiące system ...
evilsoup
3
Przeważnie jest to tutaj w celach naukowych.
MYV
5
Obowiązkowy komiks: beesbuzz.biz/d/20110224.php
puszysty

Odpowiedzi:

49

Wywołaj polecenie tak:

mkdir -- -a

Te --środki, które opcje zakończy po tym, więc -adostaje interpretować dosłownie, a nie jako opcja mkdir. Znajdziesz tę składnię nie tylko w mkdir, ale w dowolnym narzędziu zgodnym z POSIX, z wyjątkiem echoi test. Ze specyfikacji :

Argument - powinien zostać zaakceptowany jako separator wskazujący koniec opcji. Wszelkie poniższe argumenty należy traktować jako operandy, nawet jeśli zaczynają się znakiem „-”. Argumentu - nie należy używać jako opcji ani argumentu.

Użycie --jako zabezpieczenia jest zalecane w prawie każdej akcji, w której masz do czynienia z nazwami plików i chcesz się upewnić, że nie złamią one polecenia, np. Podczas przenoszenia plików w pętli możesz wywołać następujące, aby plik o nazwie -i„ t (in?) poprawnie przeanalizowane jako opcja:

mv -- "$f" new-"$f"
slhck
źródło
Minusem tego podejścia jest właśnie to, że kończy przetwarzanie opcji. Dla prostego przykładu mkdir, który działa cuda; jeśli rzeczywiście potrzebujesz opcji śledzenia nazwy pliku w wierszu poleceń, to w ogóle nie będzie działać.
CVn
1
Oczywiście - wszystko ma wadę. W przypadkach, w których masz do czynienia z nazwami plików przeplatanymi opcjami, rozwiązanie Amosa byłoby jedyną rozsądną alternatywą, jaką mogę wymyślić, ale tak naprawdę zależy to od tego, jak narzędzie analizuje opcje.
slhck
1
Ponieważ OP mówi o tworzeniu pliku o nazwie „jak argument wiersza poleceń” (załóżmy, że nazwa zaczyna się od myślnika), nie sądzę, że jest to całkowicie nieuzasadnione założenie. Weź cc -o -myfile -Wall -myfile.cjako tylko nieco wymyślony przykład. Każdy edytor wart swojej soli powinien mieć możliwość zapisania do pliku o nazwie, -myfile.cjeśli o to poprosisz, ale kompilator C prawdopodobnie nie zrobi tego, co chcesz, gdy otrzyma taką listę opcji.
CVn
1
@Maksim Na przykład polecenia, które wymagają opcji ustawiania wejściowej lub wyjściowej nazwy pliku, takie jak ccpolecenie podane powyżej przez Michaela, które ma -oopcję określenia pliku wyjściowego.
slhck
1
Przykładowa pętla Dlatego należy zawsze używać coś takiego for f in ./*; do...zamiastfor f in *; do...
evilsoup
21

Najprostszym sposobem, który powinien działać z dowolnym rozsądnym programem, jest użycie względnej nazwy ścieżki przed -, np. mkdir ./-aUtworzy katalog nazwany -aw bieżącym katalogu roboczym.

Najczęstszym przykładem użycia tej „sztuczki” jest usunięcie pliku rozpoczynającego się od myślnika, abyś mógł to zrobić rm ./-a.

Amos Shapira
źródło
3
To oczywiście działa tylko wtedy, gdy pracujesz ze ścieżkami plików, a nie dowolnymi opcjami wiersza poleceń, które są analizowane jako ciągi znaków. Ale w przeciwnym razie prefiks ./jest zawsze dobrym pomysłem - wyobraź sobie, że utworzyłeś plik o nazwie, -rfa następnie zadzwoniłeś rm *.
slhck
1
@slhck Dla wielu osób, które mogą wyglądać na żart. Ale widziałem wystarczającą liczbę przypadków, w których tego rodzaju rzeczy wymazały (część) serwera. Nie możesz wystarczająco ostrzec ludzi przed niebezpieczeństwem związanym z plikami, zaczynając od myślnika. Jedno miejsce, w którym pracowałem, miało nawet oficjalną zasadę: nigdy nie twórz pliku, którego nazwa zaczyna się od „-f” lub „-r”.
Tonny
1
To powinna być odpowiedź: to jedyny przenośny sposób ( --nie jest rozumiany przez wszystkie polecenia, tylko kilka)
Olivier Dulac
@OlivierDulac Myślałem, że to --była bash, więc powinno działać dla wszystkich programów?
gsingh2011
@ gsingh2011 nie, kod, który decyduje o tym, czy znacznik „-” jest uważany za znacznik „końca flag”, znajduje się w aplikacji i od każdej aplikacji zależy, czy traktuje to w ten sposób.
Amos Shapira
4

Powodem, mkdir '-a'lub mkdir \-anie jest praca, bo obie te metody (z wykorzystaniem cytatów lub odwrotne ukośniki) są stosowane, aby zapobiec skorupę (prawdopodobnie bash) od dając im żadnego specjalnego znaczenia. Ponieważ i -atak nie oznacza to nic specjalnego dla powłoki, nie mają one wpływu na to, jak zostanie ona przekazana mkdir.

Jeśli chodzi o mkdirto, otrzymuje listę argumentów z powłoki i nie może powiedzieć, czy umieścisz je w cudzysłowie, czy też wystąpił odwrotny ukośnik. Widzi tylko jeden argument -a. Dlatego potrzebujesz --wyjaśnienia w innych odpowiedziach.

hammar
źródło
-3

Oprócz odpowiedzi z „slhck” istnieje jeszcze jedna sztuczka, która czasem działa:

Umieść nazwę pliku w dwóch zestawach (różnych) qoutes takich jak "'-a'"lub '"-a"'.

To, czy to zadziała, zależy od programu, ale jest to ostateczność, jeśli program nie obsługuje funkcji POSIX --.
Metoda POSIX jest zawsze preferowana, ponieważ jest w 100% niezawodna.

Tonny
źródło
„Metoda POSIX jest zawsze preferowana, ponieważ jest w 100% niezawodna”. Używanie --do zakończenia przetwarzania opcji zakłada również, że nie potrzebujesz żadnych opcji śledzenia nazwy pliku, co nie zawsze ma miejsce.
CVn
@ MichaelKjörling Oczywiście ... Ale w pewnym sensie założyłem, że to byłoby oczywiste.
Tonny
4
Spowoduje to utworzenie pliku o nazwie '-a'lub "-a"przynajmniej w systemach typu BSD
nohillside
4
Można przytoczyć OS / shell gdzie to nie działa?
nohillside
1
gdyby zadziałało, wydawałoby się, że miałbyś dość znaczący problem z plikami o nazwach otoczonych znakami cudzysłowów.
muhmuhten