Что означает тире «-» в конце команды?

79

Учитывая следующую команду:

gzip -dc /cdrom/cdrom0/file.tar.gz | tar xvf 

Что означает -в конце команды? Это какой-то заполнитель?

Евгений С
источник
3
Одна небольшая деталь, которую -стоит упомянуть: не должно быть в конце команды. Например: ls -l | diff - /old_ls_output.txt.
Манатворк

Ответы:

83

В этом случае это означает «стандартный ввод». Он используется некоторыми программами (например tar), когда требуется аргумент файла, и вам нужно использовать вместо него стандартный ввод. Это не оболочка, и это зависит от программы, которую вы используете. Проверьте справочную страницу, если сомневаетесь!

В этом случае стандартный ввод является аргументом -fопции. В тех случаях, когда -это не поддерживается, вы можете использовать что-то вроде tar xvf /proc/self/fd/0или tar xvf /dev/stdin(последнее широко поддерживается в различных приложениях).

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

Алексиос
источник
4
Это также может означать STDOUT, в зависимости от контекста.
Багамат
3
И почти все остальное, поскольку это зависит от отдельных программ.
Алексиос
5
/dev/stdinили /dev/stdoutможет быть использован, если вы действительно хотите поток ввода / вывода. Обратите внимание, что это поток, программы, которые хотят искать в файле, могут не работать с ним должным образом, как в случае -(например, с ffmpeg)
Lekensteyn
3
В случае bash, дефис будет интерпретироваться оболочкой. См. Руководство по расширенному написанию сценариев Bash - Глава 3. Специальные символы , затем выполните поиск текста [тире] или «перенаправление с / на стандартный ввод или стандартный вывод». Используя bashвы можете использовать дефис в большинстве мест, ожидающих имя файла. Это очевидное дополнение к <| > ИМХО
БСД
4
Я не уверен, что это так. Во-первых, catручки -(проверьте страницу руководства). Встроенная в оболочку версия catможет или не может, но это не совсем оболочка. Кроме того, если оболочка обработана -, вы можете сказать «эхо», -и она расширится на что-то другое. Вместо этого это просто повторяет черту (не /dev/stdinили /proc/self/fd/0). И echo test > -просто создает файл с именем -, так что он явно не обрабатывает его там тоже. О, и страница, которую вы перечислили, не говорит, что она обрабатывается оболочкой , она говорит, что вы можете использовать ее с, catи diffобе они явно понимают черточки.
Алексиос
14

В этом случае, это на -самом деле довольно бесполезно, если вы используете Linux:

GNU tar (версия для Linux) принимает свой ввод от стандартного ввода по умолчанию. Если вам не нужно это поведение, и вы хотите передать имя файла в качестве аргумента командной строки, то вам нужно указать флаг f:

tar xf filename

Так что это так же, как

tar x < filename

Или, если вход gzipped как в вашем примере:

gzip -dc filename | tar x

Указывать fфлаг здесь вообще не имеет смысла , но поскольку он был указан, необходимо указать имя файла, -чтобы указать, что мы хотим читать из стандартного ввода (см. Другой ответ). Итак, повторюсь, это излишне и немного странно.

Кроме того, приведенная выше строка может быть упрощена, потому что tar GNU может быть задан поток ввода через gzipсебя, указав zфлаг:

tar xfz filename

- Не нужно звонить gzipявно.

Конрад Рудольф
источник
1
Примечание: не у каждого tarесть zвозможность.
Лиори
2
В большинстве операционных систем, кроме Linux, по tarумолчанию установлен первый ленточный накопитель по историческим причинам.
Жиль "ТАК - перестань быть злым"
1
@ Жиль и BSD, и OS X,…. Но мне любопытно: какие другие системы, кроме нескольких старых мэйнфреймов, до сих пор используют такую ​​версию (какие системы, кроме мэйнфреймов, даже имеют стример)?
Конрад Рудольф
1
@KonradRudolph Для всех трех основных BSD по умолчанию используется стример ( /dev/sa0во FreeBSD 9.0, /dev/rst0в NetBSD 6.0 и OpenBSD 5.1). AIX 7.1 по умолчанию /dev/rmt0. MINIX3 по умолчанию /dev/sa0. (Я проверял последнюю версию ОС в каждом случае, это не «старые мэйнфреймы».) Solaris настраивается через файл /etc, который, по-моему, по умолчанию используется для стримера. GNU tar, Schilling tar, OSX и BusyBox по умолчанию имеют значение stdin / stdout.
Жиль "ТАК - перестань быть злым"
1
@Gilles - по понятным причинам я перекомпилировал tarпо умолчанию второй накопитель на магнитной ленте. :)
Дэвид Харкнесс