Как «уменьшить» файл с именем «-»?

17

Я случайно создал файл с именем -(например, seq 10 > -). Затем я попытался использовать lessдля просмотра, но он просто зависает.

Я понимаю, что это происходит, потому что less -ожидает ввода от stdin, поэтому он не интерпретирует -как имя файла. Я пытался, less \-но это тоже не работает.

Итак, есть ли способ указать, lessчто -это файл, а не стандартный ввод?

Лучшее, что я мог получить:

find -name '-' -exec less {} +
fedorqui
источник
2
@muru спасибо за комментарий, но возможный дубликат настолько специфичен, что я не думаю, что он может быть «точным дубликатом». Если это было перефразировано к чему-то более общему, например, «как получить доступ к файлу, начинающемуся с« - », возможно.
Федорки
4
Это не повторяющийся вопрос. Дело в -одиночку другое. -это не вариант.
Стефан Шазелас
1
@terdon Я не думаю, что наличие одного и того же ответа напрямую означает, что они дубликаты. Где-то в Meta SO был пример: если на вопрос ответят «Нет», будет ли дубликатом что-либо, чей правильный ответ - «Нет»? Как я уже говорил, было бы интересно перефразировать кандидата-дубликата, чтобы он был более общим; в противном случае, нет смысла отправлять туда другие вопросы, подобные этому.
Федорки
4
@terdon, нет. Принятое решение здесь не сработает. И нет, -это не рассматривается как опция, это совершенно другая проблема, в случае аргументов, которые имеют форму опций.
Стефан Шазелас
2
Нет необходимости заключать в -одинарные кавычки одинаковые кавычки '-'или экранировать их, \-потому что -это не специальный символ для общих оболочек (по крайней мере, POSIX-совместимых). Результат тот же.
Пабук

Ответы:

53

Просто добавьте к нему префикс ./:

less ./-

Или используйте перенаправление:

less < -

Обратите внимание, что поскольку -(в отличие от -xили, --foo--например) считается специальным именем файла, а не параметром, следующее не работает:

less -- -   # THIS DOES NOT WORK
Говард
источник
3
Кстати, это то, что find -name '-' -exec less {} +работает.
Стефан Шазелас
6
@fedorqui, нет, это просто -и ./-(или /path/to/-или ../to/-) два (4) допустимых пути к этому -файлу, но -аргумент является специальным для less(означает чтение из stdin), но ./-не является специальным.
Стефан Шазелас
2
@fedorqui find -name '-' -exec less {} +- это нестандартная форма для find . -name '-' -exec less {} +. Он спускается по дереву в .и находит файлы и передает пути этих файлов в качестве аргументов less. Замените -exec lessна, -exec echo lessчтобы увидеть, что запускается.
Стефан Шазелас
4
@haylem, --чтобы отметить конец вариантов. Это не поможет здесь. Это -не опция, это особый аргумент без опции. См. Также unix.stackexchange.com/a/56370 , unix.stackexchange.com/a/110756
Стефан
3
@haylem, попробуй сам. --обрабатывается getopt () для обозначения конца опций, -не распознается как опция опцией getopt (), поэтому -будет распознаваться как обычный аргумент, независимо от того --, предоставлен он или нет. И как обычный аргумент, lessкак и большинство текстовых утилит, он будет воспринимать его как значение stdin, чего мы здесь не хотим.
Стефан Шазелас
3

Я бы просто mv - f && less f. Проблема решена.

snth
источник
Что ж, это работает, хотя напоминает мне о том, что НАСА потратило миллионы на разработку ручки, которая будет писать в космосе, тогда как советские космонавты использовали карандаш . Я думаю, что мы можем позволить себе инвестировать немного в исследования здесь.
Федорки
+1 зачем усложнять вещи, если существует простое решение.
Mhmd
3

Примечание: мой ответ НЕ действителен в случае OP, и применяется только к инструментам, следуя соглашению, упомянутому ниже, а не в случае файла, названного точно just -(dash), который часто также является особым случаем, чтобы указать, что чтение из стандарта вход ожидается. Смотрите принятый ответ.

Оставьте это здесь, поскольку оно содержит полезную информацию для других случаев, на которые можно наткнуться при поиске ответов.


Double-Dash это!

Используйте стандартное --соглашение double-dash ( ), чтобы указать последний аргумент:

less -- -FILENAME

пример

$ echo "meh" > -badname
$ less -badname
Number is required after -b
$ less -- -badname # GREAT SUCCESS!

Whhhaattt?

Этот --аргумент проистекает из соглашения, поддерживаемого большинством реализаций утилит оболочки и инструментов командной строки, и большинство оболочек явно рекомендуют вам следовать этому при реализации инструментов CLI.

Рекомендовано Open Group

OpenGroup также упоминает об этом в разделе описания утилит по умолчанию (v6) своей Базовой спецификации:

Поведение по умолчанию: [...] Стандартные утилиты, которые не принимают параметры, но принимают операнды, должны распознавать «-» в качестве первого аргумента, который должен быть отброшен.

Требование для распознавания «-» заключается в том, что соответствующим приложениям нужен способ защитить свои операнды от любых произвольных опций, которые реализация может предоставить в качестве расширения. Например, если стандартная утилита foo указана как не имеющая опций, и приложению необходимо указать ей путь с начальным дефисом, она смело может сделать это следующим образом:

foo -- -myfile

и избегайте проблем с использованием -m как расширения.

А в Руководстве по синтаксису утилит (v7):

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

Рекомендуется Bash

Вот выдержка из руководства bash о его встроенных функциях:

Если не указано иное, каждая встроенная команда, задокументированная в этом разделе как принимающая параметры, предшествует - принимает - для обозначения конца параметров.

Встроенные функции:, true, false и test не принимают параметры и не обрабатывают - специально. Встроенные функции exit, logout, break, continue, let и shift принимают и обрабатывают аргументы, начиная с - без необходимости -. Другие встроенные функции, которые принимают аргументы, но не указаны как принимающие параметры, интерпретируют аргументы, начинающиеся с - как недопустимые параметры и требующие - для предотвращения такой интерпретации.

Обратите внимание, что эхо не интерпретирует - означает конец опций.

Дополнительное чтение

haylem
источник
2
+1: самое портативное и независимое от команд решение, легко запоминаемое и считающееся «лучшей практикой»
mveroone
2
@ Kwaio какие-либо ссылки на "лучшую практику"? Просто чувствую любопытство по этому поводу.
Федорки
24
Этот ответ относится к аргументам, которые выглядят как варианты. Это не тот случай, для -которого это не вариант. Использование ./-или перенаправление, когда это возможно, обычно является лучшим подходом, поскольку позволяет избежать других видов проблем, таких как foo=barof awkили что -. См. Также unix.stackexchange.com/a/56370 , unix.stackexchange.com/a/110756
Стефан
7
Как говорит Стефан, это не отвечает на вопрос. less -- -все равно будет пытаться читать со стандартного ввода.
Михал Политовски
5
Вы можете удалить ответ (или переместить его на другой вопрос, поскольку здесь есть полезные ссылки) или дать понять, что он не применим к данному конкретному случаю (и, возможно, объяснить, почему это было бы еще более полезно).
Стефан Шазелас