Скрипт: Как правильно заархивировать символическую ссылку
Модераторы: /dev/random, Модераторы разделов
-
fufelok
- Сообщения: 3
Скрипт: Как правильно заархивировать символическую ссылку
Проблема такая. Как в скрипте заархивировать символическую ссылку? То есть должен архивироваться и файл назначения, и все промежуточные символические ссылки. Пример:Есть директория /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 дня уже бьюсь.
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: Скрипт: Как правильно заархивировать символическую ссылку
ну, если не работает <архиватор> <опции> /test/b, то можно попробовать <архиватор> <опции> "$(readlink -f /test/b)".
Мои розовые очки
-
drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Скрипт: Как правильно заархивировать символическую ссылку
-h, --dereference
don't dump symlinks; dump the files they point to
не?
тогда
find -L >files.lst
который потом скармливаете tar'у.
-
ZyX
- Сообщения: 355
- ОС: Gentoo
Re: Скрипт: Как правильно заархивировать символическую ссылку
Если я правильно вас понял, то попробуйте следующий скрипт:
~/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: Скрипт: Как правильно заархивировать символическую ссылку
Сложности-то какие… В скрипт не вчитывался, но, если я правильно понял задачу автора темы, она решается одной командой:
Код: Выделить всё
$ 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: Скрипт: Как правильно заархивировать символическую ссылку
t.t писал(а): ↑30.01.2011 12:28Сложности-то какие… В скрипт не вчитывался, но, если я правильно понял задачу автора темы, она решается одной командой:Код: Выделить всё
$ touch 1 $ ln -s 1 2 $ ln -s 2 3 $ readlink -f 3 /home/t/tmp/1
И то это лишь на тот случай, если используемый архиватор не умеет разыменовывать ссылки сам.
Что здесь решается? Если я правильно понял задачу автора темы, то ему надо сохранить и сам файл, и всю цепочку символических ссылок.
Объясните, как ваша команда поможет сделать следующее:
-
t.t
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Скрипт: Как правильно заархивировать символическую ссылку
Прошу прощения, значит я понял неправильно. Тогда так:ZyX писал(а): ↑30.01.2011 14:57Что здесь решается? Если я правильно понял задачу автора темы, то ему надо сохранить и сам файл, и всю цепочку символических ссылок.t.t писал(а): ↑30.01.2011 12:28Сложности-то какие… В скрипт не вчитывался, но, если я правильно понял задачу автора темы, она решается одной командой:Код: Выделить всё
$ touch 1 $ ln -s 1 2 $ ln -s 2 3 $ readlink -f 3 /home/t/tmp/1
И то это лишь на тот случай, если используемый архиватор не умеет разыменовывать ссылки сам.
Объясните, как ваша команда поможет сделать следующее:
Код: Выделить всё
while [ -L $f ]; do
echo $f
f=$(readlink $f)
done
echo $fЭто можно вставлять в tar cjf $(…) и т.п.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
t.t
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Скрипт: Как правильно заархивировать символическую ссылку
Или так:Тогда можно сразу вызывать как(не тестировал)
Код: Выделить всё
#!/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: Скрипт: Как правильно заархивировать символическую ссылку
Вы это хотя бы проверили?t.t писал(а): ↑30.01.2011 15:17Прошу прощения, значит я понял неправильно. Тогда так:ZyX писал(а): ↑30.01.2011 14:57Что здесь решается? Если я правильно понял задачу автора темы, то ему надо сохранить и сам файл, и всю цепочку символических ссылок.t.t писал(а): ↑30.01.2011 12:28Сложности-то какие… В скрипт не вчитывался, но, если я правильно понял задачу автора темы, она решается одной командой:Код: Выделить всё
$ touch 1 $ ln -s 1 2 $ ln -s 2 3 $ readlink -f 3 /home/t/tmp/1
И то это лишь на тот случай, если используемый архиватор не умеет разыменовывать ссылки сам.
Объясните, как ваша команда поможет сделать следующее:
Код: Выделить всё
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: Скрипт: Как правильно заархивировать символическую ссылку
ZyX, ничего-себе! ну вы и накрутили... зачем какие-то перловые скрипты там, где достаточно одного tar'а.
tar умеет, я проверял.
другие не нужны.
tar умеет, я проверял.
другие не нужны.
-
ZyX
- Сообщения: 355
- ОС: Gentoo
Re: Скрипт: Как правильно заархивировать символическую ссылку
Ещё один человек, не читавший первое сообщение.
tar не нужен. Уже говорилось: проблемы с UTF-8 и отсутствие возможности сделать все заголовки в начале архива.
-
fufelok
- Сообщения: 3
Re: Скрипт: Как правильно заархивировать символическую ссылку
Спасибо всем откликнувшимся за помощь. Завтра на работе протестирую
-
drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Скрипт: Как правильно заархивировать символическую ссылку
я читал.
у тара проблем с юникодом не больше, чем у этого вашего перла. или у EXT4.
заголовок прилепите сами, если так надо.
-
drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Скрипт: Как правильно заархивировать символическую ссылку
ZyX
проблемы не у тарболов, а у пользователей винрара. Если вы такой пользователь, пишите багрепорт Рошалу. Зря вы ему заплатили?
сделать переделку нормальной кодировку в вендовую - не проблема, были-бы сырцы открыты, я-бы сам сделал.
проблемы не у тарболов, а у пользователей винрара. Если вы такой пользователь, пишите багрепорт Рошалу. Зря вы ему заплатили?
сделать переделку нормальной кодировку в вендовую - не проблема, были-бы сырцы открыты, я-бы сам сделал.
-
ZyX
- Сообщения: 355
- ОС: Gentoo
Re: Скрипт: Как правильно заархивировать символическую ссылку
Тогда расскажите, какой ключ tar нужен, чтобы сохранить и всю цепочку символических ссылок, и сам файл, на который эта цепочка ссылается.
Они начнутся, если не совпадают локали машин на которых запакован архив и на которых он распаковыватся. И да, у perl могут быть проблемы с UTF-8. Но в данном случае это не важно: вполне достаточно, чтобы он отличал «/» от всех остальных байт в имени файла. А заголовки нужны, чтобы можно было не распаковывать весь архив, а распаковать сразу один файл. В случае tar, сжатого ещё чем-то это весьма затруднительно, что бы я там не приделывал.
-
t.t
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Скрипт: Как правильно заархивировать символическую ссылку
Прошу прощения ещё раз, попутал немного. Действительно всё немного сложнее:
Код: Выделить всё
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: Скрипт: Как правильно заархивировать символическую ссылку
t.t писал(а): ↑30.01.2011 22:09Прошу прощения ещё раз, попутал немного. Действительно всё немного сложнее:
Код: Выделить всё
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: Скрипт: Как правильно заархивировать символическую ссылку
dirname
Упростил для читабельности.
Честно говоря, не пробовал. Навскидку: sed 's|[^/]*/\.\.||g'. Хотя по-хорошему тут нужно с realpath переписать — даже немного проще будет.
Если такие имена есть, можно xargs -0 использовать. Но скажите: Вам сколько раз в реальной жизни попадались файлы со \n в имени?
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
ZyX
- Сообщения: 355
- ОС: Gentoo
Re: Скрипт: Как правильно заархивировать символическую ссылку
t.t писал(а): ↑31.01.2011 00:25dirname
Упростил для читабельности.
Честно говоря, не пробовал. Навскидку: sed 's|[^/]*/\.\.||g'. Хотя по-хорошему тут нужно с realpath переписать — даже немного проще будет.
Если такие имена есть, можно xargs -0 использовать. Но скажите: Вам сколько раз в реальной жизни попадались файлы со \n в имени?
Как известно, ошибки находятся, когда пользователь начинает действовать не так, как от него ожидалось. Когда я пишу что-то не для себя, я обычно проверяю работу этого чего-то с нестандартными именами файлов. Или не проверяю, но принимаю такую возможность во внимание при написании кода (так как в большинстве языков программирования особых извращений вроде тех, что приходиться делать в bash, для этого не требуется, то и проверять работу с такими файлами не надо).
-
t.t
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Скрипт: Как правильно заархивировать символическую ссылку
В данном случае я действительно зря влез: мне показалось, что задачу можно решить в одну строку, а это не так. В целом же у bash есть два неоспоримых преимущества: а) многое делается действительно в одну строку (в отличие от perl, python и т.п.); б) он есть по умолчанию почти на любой машине с GNU/Linux (в отличие от zsh, которого в 99% случаев там нет). И то, что решения, написанные быстро и под конкретный случай, не будут работать в каких-то экзотических ситуациях, возникающих раз в праздник со слабоотличимой от нуля вероятностью, при этих условиях не есть критичная проблема.ZyX писал(а): ↑31.01.2011 01:42Как известно, ошибки находятся, когда пользователь начинает действовать не так, как от него ожидалось. Когда я пишу что-то не для себя, я обычно проверяю работу этого чего-то с нестандартными именами файлов. Или не проверяю, но принимаю такую возможность во внимание при написании кода (так как в большинстве языков программирования особых извращений вроде тех, что приходиться делать в bash, для этого не требуется, то и проверять работу с такими файлами не надо).
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
fufelok
- Сообщения: 3
Re: Скрипт: Как правильно заархивировать символическую ссылку
ZyX, огромное спасибо тебе. Преписал на шелл твой код (так требуется), все работает.
-
drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Скрипт: Как правильно заархивировать символическую ссылку
а... дык tar только раскрывает ссылки. всю цепочку нужно действительно скрипт писать. только я не понимаю, кому и зачем это надо.
я знаю. решение не слишком сложное.
мы уже на эту тему спорили.
напомню: достаточно сжать каждый файл отдельно, а потом свернуть их в тарбол. получится несолидный архив, не хуже чем в винраре. ну а заголовок у солидного архива вам ничем не поможет - всё равно придётся распаковывать весь архив до нужного файла (как кстати и делает винрар, несмотря на свой заголовок).
мне попадались. я их сразу переименовывал, потому-что на них чуть менее чем все скрипты глючат. ИЧСХ мои sed-скрипты работают обычно нормально.
+100500
-
t.t
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Скрипт: Как правильно заархивировать символическую ссылку
Зачем надо, представить как раз можно. Если нужно сохранить всю структуру каталогов и файлов, то подойдёт вариант архивирования без разыменовывания ссылок — но только не в том случае, если ссылки могут ссылаться за пределы «корня» архива. В этом случае получится, что такие ссылки нужно разыменовывать, а указывающие «внутрь» — нельзя. Т.е. только вариант с обходом ссылок и остаётся.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Скрипт: Как правильно заархивировать символическую ссылку
t.t писал(а): ↑03.02.2011 15:52Зачем надо, представить как раз можно. Если нужно сохранить всю структуру каталогов и файлов, то подойдёт вариант архивирования без разыменовывания ссылок — но только не в том случае, если ссылки могут ссылаться за пределы «корня» архива. В этом случае получится, что такие ссылки нужно разыменовывать, а указывающие «внутрь» — нельзя. Т.е. только вариант с обходом ссылок и остаётся.
я-бы ограничился скриптом, который сигнализирует об ошибке, если ссылка выходит из "корня"...
-
t.t
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Скрипт: Как правильно заархивировать символическую ссылку
В конкретном случае это может быть не ошибкой, а штатной ситуацией.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: Скрипт: Как правильно заархивировать символическую ссылку
t.t писал(а): ↑03.02.2011 18:43В конкретном случае это может быть не ошибкой, а штатной ситуацией.drBatty писал(а): ↑03.02.2011 15:54я-бы ограничился скриптом, который сигнализирует об ошибке, если ссылка выходит из "корня"...t.t писал(а): ↑03.02.2011 15:52Зачем надо, представить как раз можно. Если нужно сохранить всю структуру каталогов и файлов, то подойдёт вариант архивирования без разыменовывания ссылок — но только не в том случае, если ссылки могут ссылаться за пределы «корня» архива. В этом случае получится, что такие ссылки нужно разыменовывать, а указывающие «внутрь» — нельзя. Т.е. только вариант с обходом ссылок и остаётся.
но если это штатная ситуация, то tar без всяких опций забекапит файлы и ссылки внутри периметра, и сохранит битые симлинки ведущие за периметр архива.
Тут-же предлагается бекапить резиновый периметр, который может расползаться как угодно, вот я и не могу представить практических ситуаций, когда это штатная работа скрипта...
-
t.t
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Скрипт: Как правильно заархивировать символическую ссылку
Я не автор вопроса, потому могу привести только спотолочные примеры. Первый такой пример из собственного опыта, который пришёл в голову: я занимался разработкой спецификаций и периодически мне нужно было отсылать промежуточные результаты кому-то из моих сотрудников или директоров компании. При этом сопутствующую документацию приходилось накапливать в том же каталоге (чтобы отсылать вместе), но в теории мне было бы удобнее рассортировать её где-то внутри ~/doc/ (в теории потому, что в данном случае на практике после завершения проекта мне вся эта документация оказалась больше не нужна) — вот в этом случае такие «ссылки вовне» были бы кстати.drBatty писал(а): ↑03.02.2011 19:51но если это штатная ситуация, то tar без всяких опций забекапит файлы и ссылки внутри периметра, и сохранит битые симлинки ведущие за периметр архива.
Тут-же предлагается бекапить резиновый периметр, который может расползаться как угодно, вот я и не могу представить практических ситуаций, когда это штатная работа скрипта...
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Скрипт: Как правильно заархивировать символическую ссылку
t.t писал(а): ↑03.02.2011 20:34При этом сопутствующую документацию приходилось накапливать в том же каталоге (чтобы отсылать вместе), но в теории мне было бы удобнее рассортировать её где-то внутри ~/doc/ (в теории потому, что в данном случае на практике после завершения проекта мне вся эта документация оказалась больше не нужна) — вот в этом случае такие «ссылки вовне» были бы кстати.
ИМХО ваш пример доказывает как раз обратное - архив созданный вышеописанным скриптом приведёт к созданию у заказчика, каталога ~/doc/ с вашими подкаталогами внутри. Это не нужно ни ему, ни вам (кстати, он этого ещё и не заметит, т.е. для него это будет неожиданность, когда в ЕГО ~/doc/ что-то появится). Если-же использовать tar -h, то заказчик получит свою документацию, хотя у вас там только ссылка на неё (использовать копию нельзя, т.к. лично я устану менять и сам документ, и кучу его копий)
-
t.t
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Скрипт: Как правильно заархивировать символическую ссылку
Вы неправильно поняли: я пересылал не заказчикам, а коллегам и руководству. Внутри рабочей группы такое было бы вполне нормально. А «в его doc» без «его» явно высказанного желания ничего бы не появилось, т.к. по умолчанию tar убирает начальные слеши из всех абсолютных путей внутри архива.drBatty писал(а): ↑07.02.2011 15:52ИМХО ваш пример доказывает как раз обратное - архив созданный вышеописанным скриптом приведёт к созданию у заказчика, каталога ~/doc/ с вашими подкаталогами внутри. Это не нужно ни ему, ни вам (кстати, он этого ещё и не заметит, т.е. для него это будет неожиданность, когда в ЕГО ~/doc/ что-то появится).t.t писал(а): ↑03.02.2011 20:34При этом сопутствующую документацию приходилось накапливать в том же каталоге (чтобы отсылать вместе), но в теории мне было бы удобнее рассортировать её где-то внутри ~/doc/ (в теории потому, что в данном случае на практике после завершения проекта мне вся эта документация оказалась больше не нужна) — вот в этом случае такие «ссылки вовне» были бы кстати.
Иногда архивы содержали ещё и куски прошивки, где есть свои внутренние симлинки, разыменовывать которые нельзя.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Скрипт: Как правильно заархивировать символическую ссылку
t.t писал(а): ↑07.02.2011 19:32Вы неправильно поняли: я пересылал не заказчикам, а коллегам и руководству. Внутри рабочей группы такое было бы вполне нормально. А «в его doc» без «его» явно высказанного желания ничего бы не появилось, т.к. по умолчанию tar убирает начальные слеши из всех абсолютных путей внутри архива.
дык тут и предлагают скрипты, которые обрабатывают такое:
../../../../doc/file.txt
a а ссылка вида a/b/../c/file и так отлично работает (нет выхода за периметр)
как я понял вышеприведённый скрипт, он разыменовывает ссылки за периметром. ссылки внутри и так работают, ссылки наружу можно разименовывать ключом -h. а создавать файлы за периметром не только не нужно, но и ИМХО даже опасно.