tar и его ключевые буквы: это баг или фича?

18

Мне интересно спросить разницу между этими двумя командами (т. Е. Отличаются только порядок их параметров):

  1. tar -zxvf foo.tar.gz
  2. tar -zfxv foo.tar.gz

Первый работал отлично, но второй сказал:

tar: You must specify one of the `-Acdtrux' or `--test-label'  options
Try `tar --help' or `tar --usage' for more information.

И деготь с --test-labelи -zfxvсказал:

tar (child): xv: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now

Затем я посмотрел руководство по tar и понял, что все примеры с использованием switch -fв конце !!

AFAICT нет необходимости в этом ограничении, или есть ?! потому что, на мой взгляд, переключатели должны быть бесплатными.

khikho
источник
2
@schily ваше «исправление» в командной строке скрыло, какую команду он на самом деле набрал. Начальная черта изменяет поведение GNU tar для использования другого анализатора аргументов. Не используя тире (и, следовательно, традиционный анализатор аргументов), вторая команда сработала бы.
Random832,
Дельта-распечатка из веб-системы показала мне, что вы или кто-то еще добавили -, поэтому я снова удалил ее, чтобы соответствовать тому, что система сказала мне, из OP. Но если вы правы gtar option parsing, вы обнаружили другую причину не использовать gtar.
Щил
1
-fожидает, что имя файла будет следовать. Во второй версии вы указали -fxv, что - для tar - означает, что имя файла - «xv».
Рольф
1
Обязательный XKCD .
Павел

Ответы:

11

Глядя на ваше сообщение об ошибке, очевидно, что вы не использовали, tarа скорее gtar.

В целом это может помочь понять вещи:

  • tarобычно всегда нужен аргумент файла. Если он отсутствует, он будет читать / записывать с / на реальное ленточное устройство системы по умолчанию. starизменил это в 1982 году, чтобы использовать stdin / stdout по умолчанию, и некоторые другие реализации tar (например, gtar) недавно последовали этому примеру.

  • tarне реализует ведущие -для параметров, которые вызываются key lettersв случае команды tar. Некоторые реализации позже были добавлены -в качестве букв-ключей для удобства пользователей, но вы не можете полагаться на это.

  • Способ tarсинтаксического анализа его аргументов (в частности, аргумент файла архива) является очень рискованным. Я видел много архивов tar, которые уничтожили один из файлов, которые должны быть в архиве, потому что связанный аргумент файла был взят как файл архива tar. starпо этой причине (если она starвызывается как ), не позволяет объединять «f» с другими параметрами. Если starвызывается, tarон реализует совместимость с командной строкой tar, но по-прежнему обрабатывает аргумент для буквы «f» по-разному: аргумент допустим, только если он относится к файлу реального устройства или когда (в режиме записи) файл еще не существует ,

Я рекомендую избегать рискованной оригинальной командной строки tar и использовать более безопасный синтаксис командной строки, который вы используете star.

Из-за проблемного синтаксиса командной строки tar, так называемые были tar warsв начале 1990-х. В результате paxбыла создана и стандартизирована программа (в переводе с латинского «мир» в тар-войнах). paxоднако не получил популярности, поскольку его синтаксис менее рискован, но и менее интуитивен, чем синтаксис tar. Другая проблема может быть в том, что gpaxона более или менее не поддерживается.

Шили
источник
3
Смоляные войны закончились. Гунтар победил.
Джошуа
2
Если вы были правы, почему все реализации tar копируют функции star?
Сhily
1
Кстати, смоляные войны были битвой между tarи cpio.
Щил
2
Итак, кажется, starчто -f"$file"это (в дополнение к ind) проблема с именами файлов, начинающимися с =. Поэтому нужно писать либо -f="$file"или -f "$file". Я не уверен, что назвал бы ваш звездный вариант более безопасным или современным .
Стефан Шазелас
3
-longдлинные варианты стиля несовместимы с сокращенными -xyzкороткими или -xarg. Вот почему длинные параметры в стиле X11 требуют, чтобы короткие параметры были отдельными ( -x -yне -xy), а аргументы параметров - отдельными ( xterm -n fooне xterm -nfoo). И именно поэтому в длинных опциях GNU есть дополнительная черта, чтобы устранить возможную путаницу с короткими опциями, и почему длинные опции в стиле GNU являются лучшим дизайном. Вы можете -fooсосуществовать, -x -y -xyтолько если вы очень осторожны, чтобы избежать совпадений.
Стефан Шазелас
55

Порядок ключей свободен, но -fимеет обязательный аргумент - файл tarдля чтения / записи.

Вы могли бы сделать

tar -zf foo.tar.gz -xv

и это сработает, и у вас есть требование не определенного порядка коммутаторов.

Так работают все команды с опциями, имеющими аргументы.

wurtel
источник
5
Tar не работает как другие команды, так как использует другой, намного более старый анализатор командной строки - тот же, что используется в команде "ar" и старой (до POSIX) команде "ps".
Щил
1
Спасибо за это, выбранный ответ, хотя и тщательный, не позволил мне увидеть, в чем конкретно заключалась проблема. Оглядываясь назад, кажется очевидным из сообщения об ошибке, в котором говорится, что tar пытался прочитать файл 'xv'
Джош Рамбут
1
Я полагаю, что вы также можете объявить это -f=./myfile, то есть, f принимает значение, это не флаг, а вход.
ThorSummoner
14

Традиционно параметры Тар являются более или менее «порядком свободного» (порядок из fи bвариантов имеют значения , если указаны оба). Однако использование начального дефиса заставляет GNU tar анализировать параметры таким образом, который считается более совместимым с другими командами, где указание параметра, для которого требуется аргумент (например, имя файла для f), немедленно потребляет остальную часть слова. если есть, в качестве аргумента (традиционно tar использует следующее слово в качестве имени файла / размера блока, когда fили bуказано). В вашем случае, это взяло "xv" в качестве имени файла.

Однако на такое поведение нельзя полагаться в отношении переносимости. Для максимальной переносимости вам следует избегать использования тире, всегда ставить fпоследнюю и всегда ставить пробел между fименем файла. Это, однако, упрощение, которое нарушается, если вам нужен bпараметр или вообще любой параметр (такой как C), кроме fэтого, требует аргумента.

Это описано в разделе «Три стиля» в руководстве пользователя Tar . Некоторые другие реализации (например, FreeBSD) ссылаются на опции старого стиля как «связанное слово опции». И, конечно, некоторые реализации могут поддерживать только этот тип параметров и могут или не могут игнорировать дефис, если он включен. Это единственная форма вызова, указанная в спецификации Single Unix и, следовательно, гарантированно работающая практически на всех системах.

Random832
источник
2
Обратите внимание, что некоторые реализации поддерживают другие параметры с аргументами (как Cв BSD или GNU tar. Schily tar поддерживает его как -C, но не как C, все поддерживают его как -C).
Стефан Шазелас
0

В tar переключатели « - in» устарели много лет назад и больше не нужны. Тар на самом деле раньше говорил вам, но больше не говорит.

ie:
tar zxvf foo.tar.gz
tar zfxv foo.tar.gz

Both of these work fine without the -.
Павел
источник