Что означает дефис «-» в «tar xzf -»?

23

При попытке установить Dropbox из командной строки, я читаю команды

cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf -

что -значит здесь? это предыдущий каталог?

Алгебра
источник
9
Немного педантизма: вариант, о котором вы спрашиваете, есть f -. Это может немного облегчить поиск ответа в справочных страницах.
Стадог
4
Было бы очень полезно, если бы вы могли объяснить, что именно вам не понятно в документации wgetи tar. Таким образом, соответствующие разработчики могут улучшить свою документацию, чтобы будущие пользователи больше не сталкивались с теми же проблемами. Другими словами: будь героем и сделай мир лучше!
Йорг Миттаг
2
Было бы неплохо по умолчанию для tar использовать stdin, но, поскольку наследие заключается в работе с лентами, он этого не делал. Вместо этого он узнал, как работать с файлами (с параметром f), а затем следовал соглашению, чтобы вместо имени файла для stdin было указано (в случае eXtract или stdout в случае Create)
eckes
1
@eckes В случае GNU tar стандартным является stdin , если он $TAPEне установлен.
Хрилис - на забастовку -

Ответы:

42

Некоторые команды принимают -вместо имени файла, либо:

  • Для записи в стандартный вывод, а не в именованный файл. Это то, что делает -аргумент, переданный wgetпосле -O.
  • Для чтения из стандартного ввода, а не из именованного файла. Это то, что -аргумент передан tarпосле xzf.

Показанная вами команда загружает архивный файл wgetи распаковывает его tar. Для достижения этой цели, выход wgetIS конвейера ( |) на вход tar. Вот почему wgetзапись в стандартный вывод вместо файла и tarчтение из стандартного ввода вместо файла.

Элия ​​Каган
источник
Я бы сказал «большинство команд», а не просто «некоторые команды». Я считаю, что это часть спецификации синтаксиса POSIX.
Бармар
2
@ Barar Да и нет: Рекомендация 13: Для утилит, использующих операнды для представления файлов, которые должны быть открыты для чтения или записи, операнд '-' должен использоваться для обозначения только стандартного ввода (или стандартного вывода, если это ясно из контекста, что указывается выходной файл) или файл с именем -. , Так что если - операнд для «опции файла» и имеет особое значение, то это должно быть значение stdin / stdout. Программа бесплатна, чтобы не рассматривать как особый случай и просто искать файл-
Бакуриу
(и, как правило, в этих случаях пропуск опций будет таким же, как при использовании -)
Бакуриу
@Bakuriu Я не понимаю, как это опровергает то, что я сказал. Я подозреваю, что большинство команд принимают аргументы имени файла, поэтому они должны следовать этому принципу. Но, возможно, я должен был квалифицировать это как «большинство команд, которые работают с файлами».
Бармар
1
@ Barmar Один из способов следовать руководству - вообще отказаться от обращения -с ним, рассматривая его как буквальное имя файла. Единственный способ пойти вразрез с рекомендациями - это относиться к ним -особым образом, но с другим значением, отличным от того, которое предлагает руководство.
Элия ​​Каган
12

Это просто имя файла, которое многие программы Unix интерпретируют как «вместо того, чтобы фактически открывать файл, читать из него stdin(или записывать в него stdout)».

Это означает чтение из входных данных, которые поступают в программу; в вашем случае это вывод wget.

Маркус Мюллер
источник
6
Правда ли это имя файла ?
Эрик Думинил
7
@EricDuminil Это имя файла в том смысле, что программы принимают его в некоторых местах, где в противном случае они принимают только имена файлов, но вы правы, что на самом деле речь идет не о действительном имени файла в некотором каталоге.
JoL
5
@EricDuminil: В частности, для программ, которые следуют этому соглашению, вы должны использовать, ./-если вы действительно хотите открыть файл с именем -.
Йорг Миттаг
4
@EricDuminil На самом деле: да! Она имена в File ; в смысле Unix stdin- это файловый дескриптор, и -это имя, которое вы указываете для его использования. Однако это не имя файла с точки зрения ОС. Только с точки зрения пользователя.
Маркус Мюллер
3
@rexkogitans нет. /dev/stdinэто просто имя файла удобства, предлагаемое некоторыми средствами ядра. Обычно, когда вы пишете программу, которая использует stdin, ничего не fopen("/dev/stdin", "r") происходит; Вы просто продолжаете и используете то, extern FILE* stdinчто вам предоставил ваш заголовок libc; кстати, это целочисленный дескриптор файла 0.
Маркус Мюллер
5

-Аргумент tarспецифицирует , что архив следует читать stdinвместо файла. Из руководства по GNU tar :

Если вы используете -в качестве имени архива , tarсчитывает архив из стандартного ввода (при выводе или извлечении файлов)

Другие команды имеют такое же поведение, и это определяется стандартом POSIX.1-2017 :

Руководящий принцип 13 :

Для утилит, которые используют операнды для представления файлов, которые должны быть открыты для чтения или записи, -операнд ' ' следует использовать для обозначения только стандартного ввода (или стандартного вывода, когда из контекста ясно, что файл вывода указывается) или файла им -.

Тим
источник