Як створити файл, названий як аргумент командного рядка?


29

Мені було цікаво, як зробити файл, названий як прапор, наприклад, якщо я хотів би створити папку з назвою -a, то які команди виконали би трюк?

Я намагався mkdir '-a', mkdir \-aі не працював. Я на Ubuntu.


13
Відповіді тут усі чудові, але я не можу придумати
нетролі

@evilsoup Деякі люди люблять префіксувати папки, щоб вони трималися вгорі в списку, відсортованому буквено-цифровими. Але це єдина причина, про яку я можу подумати, якщо чесно.
slhck

@slhck Я знаю принаймні один курс редагування відео, де вони заохочують студентів додавати порожні пробіли до каталогів своїх проектів, щоб вони з’являлися вгорі на комунальних iMacs. Це було некрасиво і призвело до веселої ескалації, але, принаймні, це не буде потенційно
руйнівною

3
Переважно це тут для академічного інтересу.
MYV

5
Обов’язковий комікс: beesbuzz.biz/d/20110224.php
пухнастий

Відповіді:


49

Викличте команду так:

mkdir -- -a

Це --означає, що варіанти закінчуються після цього, тому -aтрактується буквально, а не як варіант mkdir. Цей синтаксис ви знайдете не тільки в mkdir, але і будь-якій утиліті, сумісній POSIX, за винятком echoі test. З специфікації :

Аргумент - слід сприймати як роздільник, що вказує на кінець варіантів. Будь-які наступні аргументи слід розглядати як операнди, навіть якщо вони починаються із символу '-'. Аргумент - не повинен використовуватися як опція або як операнд.

Використовувати --як захисний засіб рекомендується майже для будь-яких дій, коли ви маєте справу з іменами файлів і хочете переконатися, що вони не порушують команду, наприклад, при переміщенні файлів у циклі ви можете викликати наступне, щоб файл називався -iisn ' t (in?) правильно проаналізовано як варіант:

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

Мінус цього підходу полягає саме в тому, що він припиняє обробку варіантів. На простому прикладі mkdir, який творить чудеса; якщо вам дійсно потрібна опція слідувати за ім'ям файлу в командному рядку, він взагалі не працюватиме.
CVn

1
Звичайно - у всьому є мінус. У випадках, коли ви маєте справу з іменами файлів з перемежуванням опцій, рішення Amos було б єдиною розумною альтернативою, про яку я можу придумати, але це дійсно залежить від того, як інструмент аналізує параметри.
slhck

1
Оскільки ОП говорить про створення файлу з назвою "як аргумент командного рядка" (припустимо, це означає ім'я, що починається з дефісу), я не думаю, що це абсолютно необгрунтоване припущення. Візьмемо cc -o -myfile -Wall -myfile.cлише трохи надуманий приклад. Будь-який редактор, вартий його солі, повинен мати можливість зберегти у файлі з ім'ям, -myfile.cякщо ви запитаєте його, але компілятор C, ймовірно, не зробить те, що вам хочеться, отримавши такий список параметрів.
CVn

1
@Maksim Наприклад, команди, для яких потрібна опція встановлення вхідного чи вихідного імені файлу, як ccкоманда Майкл, подана вище, яка має -oможливість вказати вихідний файл.
slhck

1
Приклад циклу - чому ви завжди повинні використовувати щось на кшталт, for f in ./*; do...а неfor f in *; do...
evilsoup

21

Найпростіший спосіб, який повинен працювати з будь-якою розумною програмою, - використовувати відносне ім’я шляху перед -, наприклад mkdir ./-a, створити каталог, який називається -aв поточному робочому каталозі.

Найпоширеніший приклад використання цього "трюку" - це коли ви хочете видалити файл, який починається з тире, так що ви можете це зробити rm ./-a.


3
Це, звичайно, робить трюк лише в тому випадку, якщо ви працюєте з шляхами файлів, а не будь-якими довільними параметрами командного рядка, які аналізуються як рядки. Але в іншому випадку префіксація ./завжди є хорошою ідеєю - уявіть, що ви створили файл, який називається, -rfа потім ви викликали rm *.
slhck

1
@slhck Для багатьох людей це може виглядати жартом. Але я бачив достатньо випадків, коли подібні речі видаляли (частину) сервера. Ви не можете попередити людей про небезпеку файлів, починаючи з тире. Одне місце, де я працював, навіть було офіційним правилом: ніколи не створюйте файл, ім'я якого починається з "-f" або "-r".
Тонні

1
На це має бути відповідь: це єдиний портативний спосіб ( --його розуміють не всі команди, лише кілька)
Олів'є Дулак

@OlivierDulac Я думав, що --це штучка, тому вона повинна працювати для всіх програм?
gsingh2011

@ gsingh2011 ні, код, який визначає, чи "-" вважається маркером "кінця прапорів", живе у програмі, і вирішувати, чи він так поводиться з ним, вирішуватиме кожен додаток.
Амос Шапіра

4

Причина , чому mkdir '-a', або mkdir \-aне працює тому , що обидва цих методу (використовуючи лапки або слеш) використовуються для запобігання пошкодження оболонки (ймовірно bash) від надання їм будь - яких особливий сенс. Оскільки так -aсамо не означає нічого особливого для оболонки, вони не впливають на те, як вона передається mkdir.

Що mkdirстосується цього, він отримує список аргументів із оболонки, і він не може сказати, вводили ви їх у лапки чи ні, чи відбувся зворотний проріз. Він просто бачить один аргумент -a. Ось чому вам потрібно те --, що пояснено в інших відповідях.


-3

На додаток до відповіді "slhck" є ще одна хитрість, яка іноді спрацьовує:

Розмістіть назву файлу в межах 2 наборів (різних) qoutes, як "'-a'"або '"-a"'.

Від того, чи це працює, залежить від програми, але це в крайньому випадку, якщо програма не підтримує функцію POSIX --.
Метод POSIX завжди є кращим, оскільки він на 100% надійний.


"Метод POSIX завжди є кращим, оскільки він на 100% надійний." Використання --для завершення обробки параметрів також передбачає, що вам не потрібно жодних параметрів для слідування імені файлу, що не завжди так.
CVn

@ MichaelKjörling Звичайно ... Але я начебто припустив, що це було б очевидно.
Тонні

4
Це створить файл під назвою '-a'або "-a", принаймні, у системах типу BSD
nohillside

4
Ви можете посилатися на ОС / оболонка , де це робить роботу?
nohillside

1
якби все-таки спрацювало, то, мабуть, у вас виникне досить значна проблема в роботі з файлами з іменами, оточеними цитатами.
muhmuhten
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.