Как создать файл с именем как аргумент командной строки?

29

Мне было интересно, как сделать файл с именем флага, например, если бы я хотел сделать папку с именем -a, какие команды добились бы цели?

Я пытался mkdir '-a', mkdir \-aи ни один не работал. Я на Ubuntu.

MYV
источник
13
Ответы здесь все великолепны, но я не могу придумать причину, по которой нет троллей, желающих сделать это ...
evilsoup
@evilsoup Некоторым людям нравится добавлять префиксы к папкам, чтобы они попадали вверху списка, отсортированного в алфавитном порядке. Но это единственная причина, по которой я могу думать, честно говоря.
slhck
@slhck Я знаю, по крайней мере, один курс по редактированию видео, где они рекомендуют учащимся добавлять пустые места в каталоги своих проектов, чтобы они появлялись на верхних строчках общих iMac. Это было некрасиво и привело к веселой эскалации, но, по крайней мере, это не могло быть потенциально разрушительным для системы ...
evilsoup
3
Главным образом это здесь для академического интереса.
MYV
5
Обязательный комикс: beesbuzz.biz/d/20110224.php
пушистый

Ответы:

49

Вызовите команду так:

mkdir -- -a

Это --означает, что после этого опции заканчиваются, поэтому -aинтерпретация интерпретируется буквально, а не как опция mkdir. Этот синтаксис вы найдете не только в mkdirлюбой POSIX-совместимой утилите, но echoи в test. Из спецификации :

Аргумент - должен быть принят в качестве разделителя, указывающего конец опций. Любые последующие аргументы должны рассматриваться как операнды, даже если они начинаются с символа «-». Аргумент - не должен использоваться как опция или как операнд.

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

mv -- "$f" new-"$f"
slhck
источник
Недостатком этого подхода является то, что он прекращает обработку опций. Для простого примера mkdir, который творит чудеса; если вам действительно нужна опция для следования имени файла в командной строке, она не будет работать вообще.
CVn
1
Конечно, есть и обратная сторона всего. В случаях, когда вы имеете дело с именами файлов, чередующимися с опциями, решение Amos было бы единственной разумной альтернативой, о которой я могу подумать, но это действительно зависит от того, как инструмент анализирует опции.
slhck
1
Поскольку OP говорит о создании файла с именем «как аргумент командной строки» (давайте предположим, что имя начинается с дефиса), я не думаю, что это абсолютно необоснованное предположение. Взять хотя 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 Я думал, что --это вещь bash, так что она должна работать для всех программ?
gsingh2011
@ gsingh2011 нет, код, который решает, считается ли «-» маркером «конца флагов», живет в приложении, и каждое приложение решает, будет ли оно обрабатывать его таким образом.
Амос Шапира
4

Причина, почему mkdir '-a'илиmkdir \-a не работает, заключается в том, что оба эти метода (с использованием кавычек или обратной косой черты) используются для предотвращения придания вашей оболочке (вероятно bash) какого-либо особого значения. Так -aкак в любом случае для оболочки ничего особенного не значит, это никак не влияет на то, как она передается mkdir.

Что mkdirкасается этого, он получает список аргументов от оболочки и не может сказать, помещены ли они в кавычки или нет, или был ли обратный слеш. Просто видит один аргумент -a. Вот почему вам нужно-- как описано в других ответах.

Хаммар
источник
-3

В дополнение к ответу от «slhck» есть еще одна хитрость, которая иногда работает:

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

Работает это или нет, зависит от программы, но это последнее средство, если программа не поддерживает --функцию POSIX .
Метод POSIX всегда предпочтителен, поскольку он надежен на 100%.

Tonny
источник
«Метод POSIX всегда предпочтителен, поскольку он надежен на 100%». Использование --для прекращения обработки опций также предполагает, что вам не нужны никакие опции для следования имени файла, что не всегда так.
CVn
@ MichaelKjörling Конечно ... Но я предположил, что это будет очевидно.
Тонни
4
Это создаст файл с именем '-a'or "-a", по крайней мере, в системах типа BSD
nohillside
4
Вы можете ссылаться на ОС / оболочка , где это делает работу?
Nohillside
1
если бы это работало, казалось бы, у вас была бы довольно серьезная проблема с файлами с именами, заключенными в кавычки.
Мухмухтен