LINUX.ORG.RU
ФорумTalks

[ЖЖ][нытик тред] tar -cf abc.iso abc.tar

 


0

1

Своими рассказами о том как я в очередной раз убил Линукс или похерил инфу самым неочевидным способом я, наверное, заработаю дурную славу на ЛОРе. Тем не менее, мое хождение по граблям, возможно, принесет пользу тем, кто на них еще не наступил, если я в очередной раз сотрясу воздух своими «почему?» и «за что?». С другой стороны глупо считать себя избранным - не я первый, не я и последний.

Нет, в этот раз я не убил Линукс. Точнее я почти его убил на прошлой неделе - во время большого обновления (включая ядро и загрузчик) системы. Когда aptitude скачал новые пакеты и начал установку - я в другом терминале с помощью MC копировал свежескачанное аниме на флешку, для просмотра на основном компьютере. Так как система ощутимо подтормаживала - я нечаянно лишний раз нажал на Enter. Впервые на моей памяти mplayer спокойно и без лишних настроек запустился в консоли и героически принялся проигрывать HD видео, но на ввод он не реагировал абсолютно. Через пару секунд все повисло и лечить данную ситуацию пришлось перезагрузкой с последующим разгребанием сломанных зависимостей и битых пакетов в aptitude.

А сегодня поутру я удачно сжал 8-ми гигабайтный образ диска до 10 кб tar-ом. tar весьма любопытная программка и засаду я почувствовал еще когда читал ман. Там честно было написано, что мануал на tar потерян в веках, а существующий был собран из комментариев к исходникам, так, что tar возможно может делать, «что-то еще». Заставить его сделать, «что-то еще» у меня получилось, попутав, входящий и выходящий файлы. Я привык, что вначале указывается входящий, а затем выходящий файл. Но в tar'е все делается совсем наоборот, что, в принципе, логично. Результат превзошел все мои ожидания, я опробовал данный способ и в Федоре, где и мануал на tar немного другой и SELinux по-умолчанию установлен и предположительно должен бы отслеживать подобную херню, но тем не менее...

tar честно намекает, что входящий и выходящий файлы как бы перепутаны местами:

[litd@main Downloads]$ tar -cf sheep.jpg sheep
tar: sheep: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

Но перед этим он молча и безжалостно убивает, в данном случае sheep.jpg. Я думаю это неправильно, возможно это даже баг. И вообще это не Unix-way - tar это не mv и не rm и он не должен делать их работу. Ну, или он хотя бы должен иметь некий ключ-предохранитель типа параметра force дабы не позволять случайно делать подобную ерунду.

Спасибо за внимание ^__^

Никогда не вляпывался в такое потому что я чётко указываю ключи и ключ -f после себя подразумевает output. Т.е. я сначала задаю параметры архива а только потом уже перечисляю что надо архивировать и никогда не ошибался. Но --force не помешал бы.

Кстати, у фряшного тара тоже были приколы. А ещё гнушный du заколебал длинным ключом --max-depth, нет чтобы как у фряшников сделать краткий ключ -d.

И у консольных комманд есть понятие usability.

true_admin ★★★★★
()
Ответ на: комментарий от Nebuchadnezzar

то есть, при tar -c sheep.jpg -f результирующим файлом выступает STDOUT

Да ну?

[litd@main Downloads]$ tar -cf sheep.jpg

tar: Cowardly refusing to create an empty archive

Try `tar --help' or `tar --usage' for more information.

ну, да, блин!

ты упоротый?

смотри:

во-первых, у -с нет параметров, это common option, которая указывает на то, что мы _создаем_ архив, в не распаковываем/выводим список файлов/етц

во-вторых, твой пример «tar -cf sheep.jpg» не является опровержением моего утверждения, потому, что у опции -f есть _ОБЯЗАТЕЛЬНЫЙ_ параметр - это файл. то есть, если ты сказал -f,то всё до следующего пробела будет именем результирующего файла. и команда твоя на русском звучит следующим образом «архивируй мне вот это НИЧЕГО, результат положи в sheep.jpg»

если хочешь попробовать, как это будет STDOUT, то либо не указывай -f вообще, либо поставь минус, как это обычно «в этих ваших линуксах» делается, чтобы указать стандартный поток вместо файла.

то есть, доводя твой «пример» до ума получаем: tar -c sheep.jpg == «создаем архив, в который помещаем sheep.jpg. пишем в STDOUT, т.к. -f не указан» или tar -cf - sheep.jpg == «создаем архив, в который помещаем sheep.jpg. пишем в STDOUT, т.к. в -f указан стандартный поток»

P.S.: поражает обилие людей, изобретающих всё новые орудия для отстреливания своих ног/рук/головы, лишь бы маны не читать!

aol ★★★★★
()

>Для первого случая есть спец. проверка (опять же см. исходники). Во втором (когда указаны несуществующие входные файлы) происходит то, что я описал.

На мой взгляд логично было бы, чтобы второй случай обрабатывался как первый или хотя бы был ключ force или предупреждение о перезаписи существуещего файла. В конце-концев есть вероятность угробить важный файл автодополнением по TABу.

у тебя своп в системе был?

Если это к вопросу о знаменитом баге - то насчет свопа не знаю, но со временем при работе с файлами/закачке торрентов система начинала работать ощутимо медленнее. На свежезагруженной системе скорость записи на флешку достигала 13 мб/сек, после дня работы 2 мб/сек. И это с ядром 2.6.24 После обновления до testing тормоза заметно ослабли.

ты упоротый?

Я понял, что «tar -c sheep.jpg -f » никаким боком к моей проблеме не относятся. Я говорю о том, что конкретно при «tar -cf sheep.jpg» и «tar -cf sheep.jpg sheep» tar получает на вход «НИЧЕГО», но в одном случае он корректно это обрабатывает и пишет «Cowardly refusing to create an empty archive», а в другом случае он зачем-то начинает писать в файл, хотя тоже должен был бы заявить «Cowardly refusing to create an empty archive». А вот при «tar -c sheep.jpg -f sheep» я вообще не понимаю, что он делает ибо он отрабатывает без ошибок, но ни sheep.jpg, ни sheep не создаются. Как результат поведение tar'а неочевидно настолько, что на нем предположительно можно писать однострочники убивающие всю инфу в home.

Nebuchadnezzar ★★★★
() автор топика
Ответ на: комментарий от Nebuchadnezzar

а в другом случае он зачем-то начинает писать в файл

нене... в первом случае на входе «ничего», а во во втором - «что-то», но произошла ошибка чтения!

а про запись в файл, смею предположить, надо глянуть в историю. Открываем эти ваши маны, читаем: «tar - The GNU version of the tape archiver (tar) utility» Изначально, tar писал на стриммеры, то есть, писал в устройство. И, видимо, именно с этим и связано такое поведение. А вообще, можно текущим maintainer-ам весточку послать :)

«научное» объяснение:

strace tar cf test.txt wft

(каталога wtf нет физически)

далее в дебрях:

open("test.txt", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
clock_gettime(CLOCK_REALTIME, {1283095314, 18539796}) = 0
lstat64("wft", 0xbf8844c8)              = -1 ENOENT (No such file or directory)
а вот если бы там O_TRUNC небыло, то ты бы себе ничего не отстрелил.. в данном случае. но в другом бы точно отстрелил!! ;) гляди: например, ты умудрился указать параметры в нужном порядке (tar -cf result.tar my_folder), но result.tar уже есть, и в него при отсутсвии O_TRUNC дописалась бы инфа. итог - отстреленная голова море крови итд.

aol ★★★★★
()
Ответ на: комментарий от aol

Значит tar'у таки нужно запретить срабатывать если результирующий файл уже существует, и добавить ключ «force rewrite». У него и так этих ключей дофига: одним больше - одним меньше не так уж и важно :)

Nebuchadnezzar ★★★★
() автор топика
Ответ на: комментарий от aol

«научное» объяснение

Экий вы затейник. Есть же исходники!

void
create_archive (void)
{
  struct name const *p;

  open_archive (ACCESS_WRITE); // <<< там в дебрях вызывается open с O_TRUNC
  buffer_write_global_xheader (); // <<< тут записывается заголовок

  if (incremental_option)
    {
      ...
      не интересно, у нас не инкрементальный случай
      ...
    }
  else
    {
      const char *name;
      while ((name = name_next (1)) != NULL) // <<< обход всех указанных для архивирования файлов
        if (!excluded_name (name))
          dump_file (name, true, (dev_t) 0); // <<< запись файла в архив
    }

  write_eot (); // <<< финализация архива
  close_archive ();
  finish_deferred_unlinks ();
  if (listed_incremental_option)
    write_directory_file ();
}
Relan ★★★★★
()
Ответ на: комментарий от Nebuchadnezzar

> Значит tar'у таки нужно запретить срабатывать если результирующий файл уже существует, и добавить ключ «force rewrite»

Запрещайте и добавляйте. Я вам даже функцию подсказал, которую править надо. Только ваш патч вряд ли примут в апстрим, потому что он сломает существующие скрипты.

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

Relan ★★★★★
()
Ответ на: комментарий от Nebuchadnezzar
Send bug reports to <bug-tar@gnu.org>.  A bug report should contain
an adequate description of the problem, your input, what you expected,
what you got, and why this is wrong.  Diffs are welcome, but they only
describe a solution, from which the problem might be uneasy to infer.
If needed, submit actual data files with your report.  Small data files
are preferred.  Big files may sometimes be necessary, but do not send them
to the report address; rather take special arrangement with the maintainer.

ы? ;)

aol ★★★★★
()
Ответ на: комментарий от Relan

<<< там в дебрях вызывается open с O_TRUNC

вооо... в дебрях ;) а в стрейсе - в первых 20 строчках ;)

такштаа, тут еще не понятно, кто из нас более затейник ;))

aol ★★★★★
()
Ответ на: комментарий от Nebuchadnezzar

кстати, чё это сразу --force-rewrite?! совместимость ломать...
продвигай лучше --noob-mode (по умолчанию выключеный!!) в котором будет овер9к проверок и вопросов ;))


и обратная совместимость и нубы довольны :-D

aol ★★★★★
()

>Запрещайте и добавляйте. Я вам даже функцию подсказал, которую править надо

Я не разумею этой мовы.

ы? ;)

Я не разумею этой мовы.

продвигай лучше --noob-mode (по умолчанию выключеный!!) в котором будет овер9к проверок и вопросов ;))

Она уже есть - вызывается ключем 'w'. Делаешь «tar -cwf sheep.jpg sheep», а он тебе: «Add sheep?». Говоришь: 'y' - он убивает sheep.jpg и выпадает с ошибкой, что sheep не существует. Говоришь: ох ять 'n'! - он убивает sheep.jpg и завершает работу. Я тащусь с этой программы :)

Nebuchadnezzar ★★★★
() автор топика
Ответ на: комментарий от Nebuchadnezzar

Я не разумею этой мовы.

мовы.

Адправіць памылка даклады <bug-tar@gnu.org>. Выпраўлена памылка ў дакладзе павінна утрымлівацца
адэкватнае апісанне праблемы, ўводу даных, што вы чакалі,
што ты атрымаў, і чаму гэта не так. Адрозненняў можна толькі вітаць, але яны толькі
апісаць раствор, з якога гэтая праблема можа быць няпроста заключыць.
У выпадку неабходнасці прадставіць фактычныя дадзеныя файлы разам са справаздачай. Маленькія файлы дадзеных
з'яўляюцца пераважнымі. Вялікія файлы часам можа быць неабходна, але не адпраўляць іх
ў дакладзе былі адлюстраваны, а, хутчэй прыняць спецыяльныя дамоўленасці з суправаджаюць.

перевожу гуголом на заказ. быстро, дёшево. :-D

aol ★★★★★
()

Но перед этим он молча и безжалостно убивает, в данном случае sheep.jpg

кг/ам

lol

21:01 ygor /home/ygor/tmp $ echo 1 > sleep.jpg
21:01 ygor /home/ygor/tmp $ echo 2 > sleep
21:01 ygor /home/ygor/tmp $ tar -cf sheep.jpg sheep
tar: sheep: Cannot stat: Нет такого файла или каталога
tar: Error exit delayed from previous errors.
21:01 ygor /home/ygor/tmp $ cat 1
cat: 1: No such file or directory
21:02 ygor /home/ygor/tmp $ cat sleep
2
21:02 ygor /home/ygor/tmp $ cat sleep.jpg
1
21:02 ygor /home/ygor/tmp $
Ygor ★★★★★
()
Ответ на: комментарий от aol
порожнеча створити_архів(порожнеча)
{
  Структура ім'я конст *р;
 
  відкрити_архів(ДОСТУП_НАПИСАТИ);
  буфера_написати_глобальної_хголова();
 
  якщо(додаткові_опції)
    {
      ...
    }
  ще
    {
      конст симв *ім'я;
      а ((ім'я = ім'я_наступному (1))! = НУЛЬ)
        якщо (!виключені_найменування(найменування))
          дамп_файлу(ім'я, правда, (прис_т) 0);
    }
 
  написати_кфл();
  закрити_архів();
  закінчити_відстрочений_зв'язок();
  якщо (наводить_додаткові_опції)
    написати_каталозі_файл();
}

Який чудовий код :)

Nebuchadnezzar ★★★★
() автор топика
Ответ на: комментарий от Nebuchadnezzar

а-а-а-а-аа!!! хохлядский одинэс!! :-D

aol ★★★★★
()
21:01 ygor /home/ygor/tmp $ echo 1 > sleep.jpg 
21:01 ygor /home/ygor/tmp $ echo 2 > sleep 
21:01 ygor /home/ygor/tmp $ tar -cf sheep.jpg sheep 
tar: sheep: Cannot stat: Нет такого файла или каталога 
tar: Error exit delayed from previous errors.

У вас bash подключен напрямую к libastral и может угадывать небольшие отклонения между sheep и sleep?

а-а-а-а-аа!!! хохлядский одинэс!! :-D

Эпическая вещь :)

Nebuchadnezzar ★★★★
() автор топика

> Но перед этим он молча и безжалостно убивает, в данном случае sheep.jpg. Я думаю это неправильно, возможно это даже баг

sheep.jpg — это параметр ключа -f. То, что указано после это колюча — это название файла, в который надо сохранить архив. В начале он будет, или в конце — зависит от тебя, а не от авторов tar. Ты просто ушлёпок, на самом деле.

name_no ★★
()
Ответ на: комментарий от name_no

>Ты просто ушлёпок, на самом деле

А вы, сударь, просто грубиян :) Более того грубиян не умеющий читать, иначе вы бы осилили эти жалкие полторы странички и врубились бы в суть проблемы.

Nebuchadnezzar ★★★★
() автор топика
Ответ на: комментарий от Nebuchadnezzar

> не умеющий читать, иначе вы бы осилили эти жалкие полторы странички и врубились бы в суть проблемы.

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

name_no ★★
()
Ответ на: комментарий от name_no

Я это понял. А теперь еще раз, специально для вас, объясняю суть вопроса. Ну не знаю я tar и боюсь напортачить, поэтому вызываю его с ключом 'w':

tar -cwf sheep.jpg sheep.tar //здесь я делаю ошибку и не замечаю этого

Add sheep.tar? //здесь я осознаю свою ошибку и жму 'n'

tar завершает свою работу. Логично, что результат его работы должен бы быть нулевым. Но тем не менее sheep.jpg успешно убит, потому что tar поспешил создать результирующий файл. Это правильно?

Ключ 'w' должен был заставить tar спрашивать пользователя перед каждым своим действием, но тем не менее о создании файла sheep.jpg он его не спросил. Это правильно?

Nebuchadnezzar ★★★★
() автор топика
Ответ на: комментарий от Nebuchadnezzar

Такс - я отправил багрепорт на ломанном английском. Позор на мою голову, но посмотрим, что ответят разработчики, если они ответят.

Nebuchadnezzar ★★★★
() автор топика
Ответ на: комментарий от Nebuchadnezzar

вобщем, погуглив и подумав, высказываю свое предположение: помнишь, говорил, что tar на ленту писал изначально. так вот, открытие устройства стриммера с флагом O_TRUNC заставляет его перематывать пленку на начало.
Ну, а при открытии простого файла - он обнуляется даже если его просто открыть с O_TRUNC и сразу закрыть.

к сожалению, внятных пруфов нет. могу ошибаться ;)

aol ★★★★★
()
Ответ на: комментарий от aol

Классная идея :) 30 лет назад в арпанете: «вот черт перепутал параметры тара и он мне стриммер перемотал». И куча комментов: «да лучше бы ты себе мозги перемотал скотина!»

Nebuchadnezzar ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.