Скрипт: Как правильно заархивировать символическую ссылку

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

fufelok
Сообщения: 3

Скрипт: Как правильно заархивировать символическую ссылку

Сообщение fufelok »

Проблема такая. Как в скрипте заархивировать символическую ссылку? То есть должен архивироваться и файл назначения, и все промежуточные символические ссылки. Пример:Есть директория /test такой структуры:
Sb_150-42:/test <545> (root) # ls -la
total 10
drwxr-xr-x 3 root root 512 Jan 28 16:48 .
drwxr-xr-x 31 root root 1024 Jan 28 15:22 ..
lrwxrwxrwx 1 root root 7 Jan 28 16:48 b -> ./te2/d
lrwxrwxrwx 1 root root 8 Jan 28 16:48 te2 -> ./tes/te
drwxr-xr-x 3 root root 512 Jan 28 16:47 tes
Полный путь /test/b это /test/tes/te/d
Соответсвенно мы тулу говорим архивировать /test/b. Он должен заархивировать:
/test/tes/te/d
/test/b -> ./te2/d
/test/te2 -> ./tes/te

При чем заранее неизвестно ничего кроме полного имени символической ссылки. Как это реализовать? Помогите плиз. 3 дня уже бьюсь.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение watashiwa_daredeska »

ну, если не работает <архиватор> <опции> /test/b, то можно попробовать <архиватор> <опции> "$(readlink -f /test/b)".
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение drBatty »

-h, --dereference
don't dump symlinks; dump the files they point to

не?
тогда
find -L >files.lst
который потом скармливаете tar'у.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение ZyX »

Если я правильно вас понял, то попробуйте следующий скрипт:

~/tmp/perl/genarfiles.pl (Created by format.vim)

#!/usr/bin/perl use strict; use warnings; use File::Basename; use File::Spec; use Cwd; $\="\n"; sub TraverseFile($$@); sub TraverseFile($$@) { my $traversed=shift; my $symlinks=shift; local $_; foreach (@_) { next if(defined $traversed->{$_}); my $oldbasename=""; my $b=$_; while($oldbasename ne $b) { next if(defined $traversed->{$b}); print STDERR ": $b"; $traversed->{$b}=1; if(-l $b) { if($b !~ /^\//) { $b=File::Spec->canonpath(Cwd::getcwd()."/$b"); } my $s=readlink $b; if($s !~ /^\//) { $s=File::Spec->canonpath(File::Basename::dirname($b)."/$s"); } print STDERR "> $b"; push @$symlinks, $b; TraverseFile($traversed, $symlinks, $s); } } continue { $oldbasename=$b; $b=File::Basename::dirname($b); } } } my $target=shift @ARGV; my $t={}; my $s=[]; local $,="\n"; TraverseFile($t, $s, @ARGV); print @$s; system tar => czvf => $target => @$s, map {Cwd::realpath($_)} @ARGV;


Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение t.t »

ZyX писал(а):
29.01.2011 23:11
Если я правильно вас понял, то попробуйте следующий скрипт:
Сложности-то какие… В скрипт не вчитывался, но, если я правильно понял задачу автора темы, она решается одной командой:

Код: Выделить всё

$ touch 1
$ ln -s 1 2
$ ln -s 2 3
$ readlink -f 3
/home/t/tmp/1

И то это лишь на тот случай, если используемый архиватор не умеет разыменовывать ссылки сам.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение ZyX »

t.t писал(а):
30.01.2011 12:28
ZyX писал(а):
29.01.2011 23:11
Если я правильно вас понял, то попробуйте следующий скрипт:
Сложности-то какие… В скрипт не вчитывался, но, если я правильно понял задачу автора темы, она решается одной командой:

Код: Выделить всё

$ touch 1
$ ln -s 1 2
$ ln -s 2 3
$ readlink -f 3
/home/t/tmp/1

И то это лишь на тот случай, если используемый архиватор не умеет разыменовывать ссылки сам.

Что здесь решается? Если я правильно понял задачу автора темы, то ему надо сохранить и сам файл, и всю цепочку символических ссылок.

Объясните, как ваша команда поможет сделать следующее:
fufelok писал(а):
28.01.2011 19:22
Полный путь /test/b это /test/tes/te/d
Соответсвенно мы тулу говорим архивировать /test/b. Он должен заархивировать:
/test/tes/te/d
/test/b -> ./te2/d
/test/te2 -> ./tes/te
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение t.t »

ZyX писал(а):
30.01.2011 14:57
t.t писал(а):
30.01.2011 12:28
ZyX писал(а):
29.01.2011 23:11
Если я правильно вас понял, то попробуйте следующий скрипт:
Сложности-то какие… В скрипт не вчитывался, но, если я правильно понял задачу автора темы, она решается одной командой:

Код: Выделить всё

$ touch 1
$ ln -s 1 2
$ ln -s 2 3
$ readlink -f 3
/home/t/tmp/1

И то это лишь на тот случай, если используемый архиватор не умеет разыменовывать ссылки сам.
Что здесь решается? Если я правильно понял задачу автора темы, то ему надо сохранить и сам файл, и всю цепочку символических ссылок.

Объясните, как ваша команда поможет сделать следующее:
fufelok писал(а):
28.01.2011 19:22
Полный путь /test/b это /test/tes/te/d
Соответсвенно мы тулу говорим архивировать /test/b. Он должен заархивировать:
/test/tes/te/d
/test/b -> ./te2/d
/test/te2 -> ./tes/te
Прошу прощения, значит я понял неправильно. Тогда так:

Код: Выделить всё

while [ -L $f ]; do
  echo $f
  f=$(readlink $f)
done
echo $f

Это можно вставлять в tar cjf $(…) и т.п.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение t.t »

Или так:

Код: Выделить всё

#!/bin/sh
tar cjf "$1" $(shift; for f in "$@"; do
  while [ -L "$f" ]; do
    echo "$f"
    f="$(readlink "$f")"
  done
  echo "$f"
done)
Тогда можно сразу вызывать как

Код: Выделить всё

скрипт архив файлы-через-пробелы
(не тестировал)
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение ZyX »

t.t писал(а):
30.01.2011 15:17
ZyX писал(а):
30.01.2011 14:57
t.t писал(а):
30.01.2011 12:28
ZyX писал(а):
29.01.2011 23:11
Если я правильно вас понял, то попробуйте следующий скрипт:
Сложности-то какие… В скрипт не вчитывался, но, если я правильно понял задачу автора темы, она решается одной командой:

Код: Выделить всё

$ touch 1
$ ln -s 1 2
$ ln -s 2 3
$ readlink -f 3
/home/t/tmp/1

И то это лишь на тот случай, если используемый архиватор не умеет разыменовывать ссылки сам.
Что здесь решается? Если я правильно понял задачу автора темы, то ему надо сохранить и сам файл, и всю цепочку символических ссылок.

Объясните, как ваша команда поможет сделать следующее:
fufelok писал(а):
28.01.2011 19:22
Полный путь /test/b это /test/tes/te/d
Соответсвенно мы тулу говорим архивировать /test/b. Он должен заархивировать:
/test/tes/te/d
/test/b -> ./te2/d
/test/te2 -> ./tes/te
Прошу прощения, значит я понял неправильно. Тогда так:

Код: Выделить всё

while [ -L $f ]; do
  echo $f
  f=$(readlink $f)
done
echo $f

Это можно вставлять в tar cjf $(…) и т.п.
Вы это хотя бы проверили?

/tmp/zsh - 4 (Created by format.vim)

(zyx:tmp/perl/test) % sh ../../bash/rl.sh ttttt.tar.bz2 b (zyx:tmp/perl/test) % tar -tjvf ttttt.tar.bz2 lrwxrwxrwx zyx/zyx 0 2011-01-29 23:00 b -> te2/d drwxr-xr-x zyx/zyx 0 2011-01-29 23:00 te2/d/ (zyx:tmp/perl/test) % ../genarfiles.pl ttttt.tar.gz b : b > /home/zyx/tmp/perl/test/b : /home/zyx/tmp/perl/test/te2/d : /home/zyx/tmp/perl/test/te2 > /home/zyx/tmp/perl/test/te2 : /home/zyx/tmp/perl/test/tes/te : /home/zyx/tmp/perl/test/tes : /home/zyx/tmp/perl/test : /home/zyx/tmp/perl : /home/zyx/tmp : /home/zyx : /home : / /home/zyx/tmp/perl/test/b /home/zyx/tmp/perl/test/te2 tar: Удаляется начальный `/' из имен объектов /home/zyx/tmp/perl/test/b /home/zyx/tmp/perl/test/te2 /home/zyx/tmp/perl/test/tes/te/d/


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

~/tmp/perl/genarfiles.pl (Created by format.vim)

#!/usr/bin/perl use strict; use warnings; use File::Basename; use File::Spec; use Cwd; $\="\n"; sub TraverseFile($$@); sub TraverseFile($$@) { my $traversed=shift; my $symlinks=shift; local $_; foreach (@_) { next if(defined $traversed->{$_}); my $oldbasename=""; my $b=$_; while($oldbasename ne $b) { next if(defined $traversed->{$b}); $traversed->{$b}=1; if(-l $b) { if($b !~ /^\//) { $b=File::Spec->canonpath(Cwd::getcwd()."/$b"); } my $s=readlink $b; if($s !~ /^\//) { $s=File::Spec->canonpath(File::Basename::dirname($b)."/$s"); } push @$symlinks, Cwd::realpath(File::Basename::dirname($b)). "/".File::Basename::basename($b); TraverseFile($traversed, $symlinks, $s); } } continue { $oldbasename=$b; $b=File::Basename::dirname($b); } } } my $target=shift @ARGV; my $t={}; my $s=[]; local $,="\n"; TraverseFile($t, $s, @ARGV); print @$s; system tar => czvf => $target => @$s, map {Cwd::realpath($_)} @ARGV;



t.t писал(а):
30.01.2011 15:24
Или так:

Код: Выделить всё

#!/bin/sh
tar cjf "$1" $(shift; for f in "$@"; do
  while [ -L "$f" ]; do
    echo "$f"
    f="$(readlink "$f")"
  done
  echo "$f"
done)
Тогда можно сразу вызывать как

Код: Выделить всё

скрипт архив файлы-через-пробелы
(не тестировал)

Зря не тестировали. Во-первых, $() в аргументах — это уже проблема с пробелами, тут гораздо более уместны массивы. Во-вторых, вы не учитываете случай, когда надо заархивировать символическую ссылку, не являющуюся последним компонентом пути.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение drBatty »

ZyX, ничего-себе! ну вы и накрутили... зачем какие-то перловые скрипты там, где достаточно одного tar'а.
t.t писал(а):
30.01.2011 12:28
И то это лишь на тот случай, если используемый архиватор не умеет разыменовывать ссылки сам.

tar умеет, я проверял.
другие не нужны.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение ZyX »

drBatty писал(а):
30.01.2011 18:25
ZyX, ничего-себе! ну вы и накрутили... зачем какие-то перловые скрипты там, где достаточно одного tar'а.
t.t писал(а):
30.01.2011 12:28
И то это лишь на тот случай, если используемый архиватор не умеет разыменовывать ссылки сам.

tar умеет, я проверял.
другие не нужны.

Ещё один человек, не читавший первое сообщение.


drBatty писал(а):
30.01.2011 18:25
tar умеет, я проверял.
другие не нужны.

tar не нужен. Уже говорилось: проблемы с UTF-8 и отсутствие возможности сделать все заголовки в начале архива.
Спасибо сказали:
fufelok
Сообщения: 3

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение fufelok »

Спасибо всем откликнувшимся за помощь. Завтра на работе протестирую
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение drBatty »

ZyX писал(а):
30.01.2011 18:44
Ещё один человек, не читавший первое сообщение.

я читал.
ZyX писал(а):
30.01.2011 18:44
tar не нужен. Уже говорилось: проблемы с UTF-8 и отсутствие возможности сделать все заголовки в начале архива.

у тара проблем с юникодом не больше, чем у этого вашего перла. или у EXT4.
заголовок прилепите сами, если так надо.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение drBatty »

ZyX
проблемы не у тарболов, а у пользователей винрара. Если вы такой пользователь, пишите багрепорт Рошалу. Зря вы ему заплатили?
сделать переделку нормальной кодировку в вендовую - не проблема, были-бы сырцы открыты, я-бы сам сделал.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение ZyX »

drBatty писал(а):
30.01.2011 20:09
ZyX писал(а):
30.01.2011 18:44
Ещё один человек, не читавший первое сообщение.

я читал.

Тогда расскажите, какой ключ tar нужен, чтобы сохранить и всю цепочку символических ссылок, и сам файл, на который эта цепочка ссылается.
drBatty писал(а):
30.01.2011 20:09
ZyX писал(а):
30.01.2011 18:44
tar не нужен. Уже говорилось: проблемы с UTF-8 и отсутствие возможности сделать все заголовки в начале архива.

у тара проблем с юникодом не больше, чем у этого вашего перла. или у EXT4.
заголовок прилепите сами, если так надо.

Они начнутся, если не совпадают локали машин на которых запакован архив и на которых он распаковыватся. И да, у perl могут быть проблемы с UTF-8. Но в данном случае это не важно: вполне достаточно, чтобы он отличал «/» от всех остальных байт в имени файла. А заголовки нужны, чтобы можно было не распаковывать весь архив, а распаковать сразу один файл. В случае tar, сжатого ещё чем-то это весьма затруднительно, что бы я там не приделывал.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение t.t »

ZyX писал(а):
30.01.2011 16:57
Вы это хотя бы проверили?
Прошу прощения ещё раз, попутал немного. Действительно всё немного сложнее:

Код: Выделить всё

find $1 -type f -o -type l |
  while read f; do
    while [ -L $f ]; do
      echo $f
      [ / = $(readlink $f | cut -c1) ] &&
        f=$(readlink $f) ||
        f=$(dirname $f)/$(readlink $f)
    done
    [ -f $f ] && {
      l=$f
      while [ -n "$l" -a "$l" != . -a "$l" != / ]; do
        l=$(dirname $l)
        [ -L $l ] && unset l
      done
      [ -n "$l" ] && echo $f
    }
  done


Для проверки положил рядом с d ещё один симлинк, указывающий за пределы каталога test — иначе было бы достаточно одного find-а:

Код: Выделить всё

$ find test/ -type f -o -type l | while read f; do while [ -L $f ]; do echo $f; [ / = $(readlink $f | cut -c1) ] && f=$(readlink $f) || f=$(dirname $f)/$(readlink $f); done; [ -f $f ] && { l=$f; while [ -n "$l" -a "$l" != . -a "$l" != / ]; do l=$(dirname $l); [ -L $l ] && unset l; done; [ -n "$l" ] && echo $f; }; done
test/tes/te/d
test/tes/te/a
/home/t/tmp/e
test/te2
test/b
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение ZyX »

t.t писал(а):
30.01.2011 22:09
ZyX писал(а):
30.01.2011 16:57
Вы это хотя бы проверили?
Прошу прощения ещё раз, попутал немного. Действительно всё немного сложнее:

Код: Выделить всё

find $1 -type f -o -type l |
  while read f; do
    while [ -L $f ]; do
      echo $f
      [ / = $(readlink $f | cut -c1) ] &&
        f=$(readlink $f) ||
        f=$(dirname $f)/$(readlink $f)
    done
    [ -f $f ] && {
      l=$f
      while [ -n "$l" -a "$l" != . -a "$l" != / ]; do
        l=$(dirname $l)
        [ -L $l ] && unset l
      done
      [ -n "$l" ] && echo $f
    }
  done


Для проверки положил рядом с d ещё один симлинк, указывающий за пределы каталога test — иначе было бы достаточно одного find-а:

Код: Выделить всё

$ find test/ -type f -o -type l | while read f; do while [ -L $f ]; do echo $f; [ / = $(readlink $f | cut -c1) ] && f=$(readlink $f) || f=$(dirname $f)/$(readlink $f); done; [ -f $f ] && { l=$f; while [ -n "$l" -a "$l" != . -a "$l" != / ]; do l=$(dirname $l); [ -L $l ] && unset l; done; [ -n "$l" ] && echo $f; }; done
test/tes/te/d
test/tes/te/a
/home/t/tmp/e
test/te2
test/b


Не совсем понял, как им пользоваться, но во-первых, ему надо указывать test/b, а не test. Во-вторых, это ведь bash? Где двойные штрихи вокруг переменных? В-третьих, вы пробовали скормить tar’у пути, содержащие «..»? Получается вот такое:

/tmp/zsh - 1 (Created by format.vim)

(zyx:~/tmp/zsh) % tar -czvf a.tar.gz $PWD/../perl/test/../../zsh/rl.zsh tar: Удаляется начальный `/home/zyx/tmp/zsh/../perl/test/../../' из имен объектов /home/zyx/tmp/zsh/../perl/test/../../zsh/rl.zsh (zyx:~/tmp/zsh) % tar -tzvf a.tar.gz -rwxr-xr-x zyx/zyx 405 2011-01-30 23:46 zsh/rl.zsh


Если надо правильно сохранить все возможные символические ссылки, то остаётся только сделать корень архива == корень файловой системы. А здесь это не так. Собственно, это и было проблемой старой версии моего скрипта. И та же проблема у вас, если в символической ссылке попадётся путь с «..». В-четвёртых, find test | read не будет работать, если test — реально \ \ \ dir и если где-то попадётся \n в имени файла. perl’у же совершенно без разницы, какие байты будут в имени файла; того же можно добиться, используя zsh вместо bash+find.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение t.t »

ZyX писал(а):
31.01.2011 00:02
Не совсем понял, как им пользоваться, но во-первых, ему надо указывать test/b, а не test.
dirname

ZyX писал(а):
31.01.2011 00:02
Во-вторых, это ведь bash? Где двойные штрихи вокруг переменных?
Упростил для читабельности.

ZyX писал(а):
31.01.2011 00:02
В-третьих, вы пробовали скормить tar’у пути, содержащие «..»?
Честно говоря, не пробовал. Навскидку: sed 's|[^/]*/\.\.||g'. Хотя по-хорошему тут нужно с realpath переписать — даже немного проще будет.

ZyX писал(а):
31.01.2011 00:02
В-четвёртых, find test | read не будет работать, если test— реально \ \ \ dir и если где-то попадётся \n в имени файла. perl’у же совершенно без разницы, какие байты будут в имени файла; того же можно добиться, используя zsh вместо bash+find.
Если такие имена есть, можно xargs -0 использовать. Но скажите: Вам сколько раз в реальной жизни попадались файлы со \n в имени?
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение ZyX »

t.t писал(а):
31.01.2011 00:25
ZyX писал(а):
31.01.2011 00:02
Не совсем понял, как им пользоваться, но во-первых, ему надо указывать test/b, а не test.
dirname

ZyX писал(а):
31.01.2011 00:02
Во-вторых, это ведь bash? Где двойные штрихи вокруг переменных?
Упростил для читабельности.

ZyX писал(а):
31.01.2011 00:02
В-третьих, вы пробовали скормить tar’у пути, содержащие «..»?
Честно говоря, не пробовал. Навскидку: sed 's|[^/]*/\.\.||g'. Хотя по-хорошему тут нужно с realpath переписать — даже немного проще будет.

ZyX писал(а):
31.01.2011 00:02
В-четвёртых, find test | read не будет работать, если test— реально \ \ \ dir и если где-то попадётся \n в имени файла. perl’у же совершенно без разницы, какие байты будут в имени файла; того же можно добиться, используя zsh вместо bash+find.
Если такие имена есть, можно xargs -0 использовать. Но скажите: Вам сколько раз в реальной жизни попадались файлы со \n в имени?

Как известно, ошибки находятся, когда пользователь начинает действовать не так, как от него ожидалось. Когда я пишу что-то не для себя, я обычно проверяю работу этого чего-то с нестандартными именами файлов. Или не проверяю, но принимаю такую возможность во внимание при написании кода (так как в большинстве языков программирования особых извращений вроде тех, что приходиться делать в bash, для этого не требуется, то и проверять работу с такими файлами не надо).
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение t.t »

ZyX писал(а):
31.01.2011 01:42
Как известно, ошибки находятся, когда пользователь начинает действовать не так, как от него ожидалось. Когда я пишу что-то не для себя, я обычно проверяю работу этого чего-то с нестандартными именами файлов. Или не проверяю, но принимаю такую возможность во внимание при написании кода (так как в большинстве языков программирования особых извращений вроде тех, что приходиться делать в bash, для этого не требуется, то и проверять работу с такими файлами не надо).
В данном случае я действительно зря влез: мне показалось, что задачу можно решить в одну строку, а это не так. В целом же у bash есть два неоспоримых преимущества: а) многое делается действительно в одну строку (в отличие от perl, python и т.п.); б) он есть по умолчанию почти на любой машине с GNU/Linux (в отличие от zsh, которого в 99% случаев там нет). И то, что решения, написанные быстро и под конкретный случай, не будут работать в каких-то экзотических ситуациях, возникающих раз в праздник со слабоотличимой от нуля вероятностью, при этих условиях не есть критичная проблема.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
fufelok
Сообщения: 3

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение fufelok »

ZyX, огромное спасибо тебе. Преписал на шелл твой код (так требуется), все работает.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение drBatty »

ZyX писал(а):
30.01.2011 21:16
Тогда расскажите, какой ключ tar нужен, чтобы сохранить и всю цепочку символических ссылок, и сам файл, на который эта цепочка ссылается.

а... дык tar только раскрывает ссылки. всю цепочку нужно действительно скрипт писать. только я не понимаю, кому и зачем это надо.
ZyX писал(а):
30.01.2011 21:16
Они начнутся, если не совпадают локали машин на которых запакован архив и на которых он распаковыватся.

я знаю. решение не слишком сложное.
ZyX писал(а):
30.01.2011 21:16
А заголовки нужны, чтобы можно было не распаковывать весь архив, а распаковать сразу один файл. В случае tar, сжатого ещё чем-то это весьма затруднительно, что бы я там не приделывал.

мы уже на эту тему спорили.
напомню: достаточно сжать каждый файл отдельно, а потом свернуть их в тарбол. получится несолидный архив, не хуже чем в винраре. ну а заголовок у солидного архива вам ничем не поможет - всё равно придётся распаковывать весь архив до нужного файла (как кстати и делает винрар, несмотря на свой заголовок).
t.t писал(а):
31.01.2011 00:25
Но скажите: Вам сколько раз в реальной жизни попадались файлы со \n в имени?

мне попадались. я их сразу переименовывал, потому-что на них чуть менее чем все скрипты глючат. ИЧСХ мои sed-скрипты работают обычно нормально.
t.t писал(а):
31.01.2011 09:37
И то, что решения, написанные быстро и под конкретный случай, не будут работать в каких-то экзотических ситуациях, возникающих раз в праздник со слабоотличимой от нуля вероятностью, при этих условиях не есть критичная проблема.

+100500
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение t.t »

drBatty писал(а):
03.02.2011 15:30
ZyX писал(а):
30.01.2011 21:16
Тогда расскажите, какой ключ tar нужен, чтобы сохранить и всю цепочку символических ссылок, и сам файл, на который эта цепочка ссылается.
а... дык tar только раскрывает ссылки. всю цепочку нужно действительно скрипт писать. только я не понимаю, кому и зачем это надо.
Зачем надо, представить как раз можно. Если нужно сохранить всю структуру каталогов и файлов, то подойдёт вариант архивирования без разыменовывания ссылок — но только не в том случае, если ссылки могут ссылаться за пределы «корня» архива. В этом случае получится, что такие ссылки нужно разыменовывать, а указывающие «внутрь» — нельзя. Т.е. только вариант с обходом ссылок и остаётся.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение drBatty »

t.t писал(а):
03.02.2011 15:52
Зачем надо, представить как раз можно. Если нужно сохранить всю структуру каталогов и файлов, то подойдёт вариант архивирования без разыменовывания ссылок — но только не в том случае, если ссылки могут ссылаться за пределы «корня» архива. В этом случае получится, что такие ссылки нужно разыменовывать, а указывающие «внутрь» — нельзя. Т.е. только вариант с обходом ссылок и остаётся.

я-бы ограничился скриптом, который сигнализирует об ошибке, если ссылка выходит из "корня"...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение t.t »

drBatty писал(а):
03.02.2011 15:54
t.t писал(а):
03.02.2011 15:52
Зачем надо, представить как раз можно. Если нужно сохранить всю структуру каталогов и файлов, то подойдёт вариант архивирования без разыменовывания ссылок — но только не в том случае, если ссылки могут ссылаться за пределы «корня» архива. В этом случае получится, что такие ссылки нужно разыменовывать, а указывающие «внутрь» — нельзя. Т.е. только вариант с обходом ссылок и остаётся.
я-бы ограничился скриптом, который сигнализирует об ошибке, если ссылка выходит из "корня"...
В конкретном случае это может быть не ошибкой, а штатной ситуацией.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение drBatty »

t.t писал(а):
03.02.2011 18:43
drBatty писал(а):
03.02.2011 15:54
t.t писал(а):
03.02.2011 15:52
Зачем надо, представить как раз можно. Если нужно сохранить всю структуру каталогов и файлов, то подойдёт вариант архивирования без разыменовывания ссылок — но только не в том случае, если ссылки могут ссылаться за пределы «корня» архива. В этом случае получится, что такие ссылки нужно разыменовывать, а указывающие «внутрь» — нельзя. Т.е. только вариант с обходом ссылок и остаётся.
я-бы ограничился скриптом, который сигнализирует об ошибке, если ссылка выходит из "корня"...
В конкретном случае это может быть не ошибкой, а штатной ситуацией.

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

Тут-же предлагается бекапить резиновый периметр, который может расползаться как угодно, вот я и не могу представить практических ситуаций, когда это штатная работа скрипта...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение t.t »

drBatty писал(а):
03.02.2011 19:51
но если это штатная ситуация, то tar без всяких опций забекапит файлы и ссылки внутри периметра, и сохранит битые симлинки ведущие за периметр архива.

Тут-же предлагается бекапить резиновый периметр, который может расползаться как угодно, вот я и не могу представить практических ситуаций, когда это штатная работа скрипта...
Я не автор вопроса, потому могу привести только спотолочные примеры. Первый такой пример из собственного опыта, который пришёл в голову: я занимался разработкой спецификаций и периодически мне нужно было отсылать промежуточные результаты кому-то из моих сотрудников или директоров компании. При этом сопутствующую документацию приходилось накапливать в том же каталоге (чтобы отсылать вместе), но в теории мне было бы удобнее рассортировать её где-то внутри ~/doc/ (в теории потому, что в данном случае на практике после завершения проекта мне вся эта документация оказалась больше не нужна) — вот в этом случае такие «ссылки вовне» были бы кстати.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение drBatty »

t.t писал(а):
03.02.2011 20:34
При этом сопутствующую документацию приходилось накапливать в том же каталоге (чтобы отсылать вместе), но в теории мне было бы удобнее рассортировать её где-то внутри ~/doc/ (в теории потому, что в данном случае на практике после завершения проекта мне вся эта документация оказалась больше не нужна) — вот в этом случае такие «ссылки вовне» были бы кстати.

ИМХО ваш пример доказывает как раз обратное - архив созданный вышеописанным скриптом приведёт к созданию у заказчика, каталога ~/doc/ с вашими подкаталогами внутри. Это не нужно ни ему, ни вам (кстати, он этого ещё и не заметит, т.е. для него это будет неожиданность, когда в ЕГО ~/doc/ что-то появится). Если-же использовать tar -h, то заказчик получит свою документацию, хотя у вас там только ссылка на неё (использовать копию нельзя, т.к. лично я устану менять и сам документ, и кучу его копий)

http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение t.t »

drBatty писал(а):
07.02.2011 15:52
t.t писал(а):
03.02.2011 20:34
При этом сопутствующую документацию приходилось накапливать в том же каталоге (чтобы отсылать вместе), но в теории мне было бы удобнее рассортировать её где-то внутри ~/doc/ (в теории потому, что в данном случае на практике после завершения проекта мне вся эта документация оказалась больше не нужна) — вот в этом случае такие «ссылки вовне» были бы кстати.
ИМХО ваш пример доказывает как раз обратное - архив созданный вышеописанным скриптом приведёт к созданию у заказчика, каталога ~/doc/ с вашими подкаталогами внутри. Это не нужно ни ему, ни вам (кстати, он этого ещё и не заметит, т.е. для него это будет неожиданность, когда в ЕГО ~/doc/ что-то появится).
Вы неправильно поняли: я пересылал не заказчикам, а коллегам и руководству. Внутри рабочей группы такое было бы вполне нормально. А «в его doc» без «его» явно высказанного желания ничего бы не появилось, т.к. по умолчанию tar убирает начальные слеши из всех абсолютных путей внутри архива.

drBatty писал(а):
07.02.2011 15:52
Если-же использовать tar -h, то заказчик получит свою документацию, хотя у вас там только ссылка на неё (использовать копию нельзя, т.к. лично я устану менять и сам документ, и кучу его копий)
Иногда архивы содержали ещё и куски прошивки, где есть свои внутренние симлинки, разыменовывать которые нельзя.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Скрипт: Как правильно заархивировать символическую ссылку

Сообщение drBatty »

t.t писал(а):
07.02.2011 19:32
Вы неправильно поняли: я пересылал не заказчикам, а коллегам и руководству. Внутри рабочей группы такое было бы вполне нормально. А «в его doc» без «его» явно высказанного желания ничего бы не появилось, т.к. по умолчанию tar убирает начальные слеши из всех абсолютных путей внутри архива.

дык тут и предлагают скрипты, которые обрабатывают такое:
../../../../doc/file.txt
a а ссылка вида a/b/../c/file и так отлично работает (нет выхода за периметр)

t.t писал(а):
07.02.2011 19:32
Иногда архивы содержали ещё и куски прошивки, где есть свои внутренние симлинки, разыменовывать которые нельзя.

как я понял вышеприведённый скрипт, он разыменовывает ссылки за периметром. ссылки внутри и так работают, ссылки наружу можно разименовывать ключом -h. а создавать файлы за периметром не только не нужно, но и ИМХО даже опасно.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали: