Почему команды cat, grep и другие команды не могут понять файлы, начинающиеся с знака «минус»?

Если у меня есть файл, имя которого начинается с одного или нескольких знаков минус, например, --1 он не может использоваться как параметр для многих команд. Даже если я бегу

 cat --1 

вместо содержимого файла я получаю нераспознанное сообщение об ошибке опции:

 cat: unrecognized option '--1' 

Тот же эффект появляется при вводе

 cat "--1" cat '--1' cat \-\-1 

ничего не работает. Файлы, начинающиеся с '-', не являются незаконными в файловой системе, но работать с ними в cli и скриптах довольно сложно. Хорошо, в случае cat или grep я могу использовать

 cat <--1 

и это будет работать, но

 rm --1 

тоже не будет работать, и довольно сложно подставить эту команду чем-то другим. Очень неудобно в конце концов. Существует ли универсальное обходное решение, отличное от того, чтобы не использовать такие имена файлов?

BTW, если файл имен один - и все большинство команд поймут его как stdin , не так ли?

И было бы трудно не использовать такие имена файлов, так как я не могу переименовать их все в скрипте, используя команду mv .

4 Solutions collect form web for “Почему команды cat, grep и другие команды не могут понять файлы, начинающиеся с знака «минус»?”

Соглашение состоит в том, что все, что начинается с a, - это вариант. Это сталкивается с именами файлов, которые начинаются с - . Чтобы обойти это, большинство команд распознают -- как дозорный пункт конца опций. Все после -- не будут распознаваться как опции, а будут восприниматься буквально как имена файлов.

Например

 cat -- --1 

или

 rm -rf -- --1 

Другой метод – определить имя файла с помощью пути.

например

 cat ./--1 

или даже

 cat /home/username/foo/--1 

Лучше всего никогда не создавать имена файлов, которые начинаются с - . Имена файлов могут содержать все виды символов, включая новую строку, но только потому, что это возможно, это не значит, что вы должны это делать.

Чтобы ответить на ваш вопрос: почему команды cat, grep и другие команды не могут понять файлы, начинающиеся с знака «минус»? Потому что командная строка – это просто строка. Оболочка делает некоторое расширение имени файла и некоторое разбиение слов и замену переменных, но в конце программа получает массив строк.

Как вы отделяете строки, которые означают опции из строк, которые означают имена файлов? Некоторыми дозорными персонажами. Соглашение в мире unix / linux должно использовать - как персонаж дозорного. Все, что начинается с - это вариант. Ну, почти все. Аргументы для параметров также могут начинаться с - , но это детали отдельной программы.

Не каждая программа соответствует этому соглашению. Вероятно, самым популярным примером является dd :

 dd if=/dev/random of=whatfreespace 

dd распознает имена файлов, потому что они появляются после знака = .

Большинство, если не все, программы GNU соответствуют GNU getopt конвенции: короткие параметры начинаются с - и только один символ, длинные варианты начинаются с -- и имеют как минимум два символа. -- по собственному значению конец опций и все строки после этого знака не распознаются как опции. Для получения более подробной информации ознакомьтесь с инструкциями синтаксиса аргументов программы в руководстве GNU libc.

Один пример программы, которая только частично соответствует конвенции GNU, find :

 find -not -name porn -delete 

Хотя find использует - чтобы отличать опции от не-опций, он не отличается длинными опциями из коротких опций. Он распознает -- как конец опций. Каждая программа может определить свой собственный способ распознавания опций и имен файлов и всего остального.

Соглашение об интерпретации единственного - как stdin – это просто соглашение о том, как интерпретировать односимвольный символ, когда он встречается в массиве строк.

Все, что начинается с тире, считается опцией. Вы можете добавить путь к имени файла, чтобы он не выглядел как опция:

 cat ./--filename 

Использование cat -- --filename указывает на прекращение поиска любой опции. Есть потенциальные проблемы с этим подходом, поскольку сторонние приложения не знают, как обрабатывать имена разбитых файлов. Однако двоичные файлы POSIX, такие как cp, rm, cat т. Д., Знают, как обрабатывать эти тире

В более общем плане это:

 cat $options_and_or_file_patterns_or_stdin_if_dash cat "$option_or_file_or_stdin_if_dash" cat -- "$file_or_stdin_if_dash" cat < "$file" cat - < "$file" # same as above 
  • перечислить файлы и сохранить их в переменных
  • встроенная функция экспорта bash
  • Выполните команду для всех файлов в дереве каталогов и поместите вывод в переменную
  • Что означает это регулярное выражение?
  • Как отображать «доступные для человека» размеры файлов в результатах поиска?
  • gunzip папку со многими файлами
  • Снять демона с помощью sudo?
  • Использовать оболочку, не установленную на удаленном компьютере
  • Как загрузить последний файл в папке с помощью scp?
  • Как искать одиночные кавычки и двойные кавычки в поиске grep?
  • Изменяет ли gnome-терминал PATH при вызове оболочки
  • Linux и Unix - лучшая ОС в мире.