Например, если символьная ссылка
a -> b
b -> c
c -> d
скажите, уровень символьной ссылки 3.
Затем есть ли какая-либо утилита для получения этой информации? И, также я хочу получить деталь расширения символьной ссылки, которая покажет мне что-то как:
1. /abc/xyz is expanded to /abc/xy/z (lrwx--x--x root root)
2. /abc/xy/z is expanded to /abc/xy-1.3.2/z (lrwx--x--x root root)
3. /abc/xy-1.3.2/z is expanded to /abc/xy-1.3.2/z-4.6 (lrwx--x--x root root)
4. /abc/xy-1.3.2/z-4.6 is expanded to /storage/121/43/z_4_6 (lrwx--x--x root root)
5. /storage/121/43/z_4_6 is expanded to /media/kitty_3135/43/z_4_6 (lrwx--x--x root root)
Таким образом, я могу диагностика с символьными ссылками. Какая-либо идея?
Эта рекурсивная функция Bash распечатает цепочку ссылки и количество плюс диагностика:
chain() { local link target; if [[ -z $_chain ]]; then unset _chain_count _expansion; _chain="$1"; fi; link=$(stat --printf=%N $1); while [[ $link =~ \-\> ]]; do target="${link##*\`}"; target="${target%\'}"; _chain+=" -> $target"; ((_chain_count++)); _expansion+="$_chain_count. $1 is expanded to $target $(stat --printf="(%A %U %G)" $target)"$'\n'; chain "$target"; return; done; echo "$_chain ($_chain_count)"; echo "$_expansion"; unset _chain _chain_count _expansion; }
Это требует stat
. Для получения дополнительной информации и версия, которая использует readlink
вместо stat
, см. мой ответ здесь (опция количества должна была бы быть добавлена, но добавление полномочий и владельца/группы будет немного более сложным).
Для этого:
a
b -> a
c -> b
d -> c
Вывод chain d
был бы:
d -> c -> b -> a (3)
1. d is expanded to c (lrwxrwxrwx username groupname)
2. c is expanded to b (lrwxrwxrwx username groupname)
3. b is expanded to a (-rw-r--r-- root root)
Вот более читаемая версия функции:
chain ()
{
local link target;
if [[ -z $_chain ]]; then
unset _chain_count _expansion;
_chain="$1";
fi;
link=$(stat --printf=%N $1);
while [[ $link =~ \-\> ]]; do
target="${link##*\`}";
target="${target%\'}";
_chain+=" -> $target";
((_chain_count++));
_expansion+="$_chain_count. $1 is expanded to $target $(stat --printf="(%A %U %G)" $target)"$'\n';
chain "$target";
return;
done;
echo "$_chain ($_chain_count)";
echo "$_expansion";
unset _chain _chain_count _expansion
}
Это на самом деле довольно хитро, в целом, так как у Вас могла быть символьная ссылка, такая как:
ln -s ../symlink/xyz pqr
где 'символьная ссылка' является самостоятельно символьной ссылкой некоторой произвольной длины. У меня есть программа, которая делает то же задание как realpath()
но который также проверяет безопасность всех символьных ссылок на пути. По сути, это могло использоваться для ответа на вопрос. И некоторые его сценарии тестирования могли использоваться для проверки вычислений.
Это - один такой тест:
#!/bin/ksh
#
# @(#)$Id: realpathtest.sh,v 1.4 2008/04/14 19:36:54 jleffler Exp $
#
# Create confusing path names
base=${1:-"./rpt"}
mkdir -p $base/elsewhere/confused $base/elsewhere/hidden \
$base/other/place $base/elsewhere/private
(
cd $base
[ -h link ] || ln -s elsewhere/confused link
[ -h some ] || ln -s other/place some
)
(
cd $base/elsewhere/confused
[ -h mischief ] || ln -s ../hidden mischief
[ -h where ] || ln -s ../private where
)
(
cd $base/other/place
[ -h dubious ] || ln -s ../../link/mischief dubious
[ -h doubtful ] || ln -s ../../link/where doubtful
)
(
cd $base/elsewhere/private
echo "What is the real pathname for $base/some/doubtful/file?" > file
)
(
cd $base/elsewhere/hidden
[ -h file ] || ln -s name file
echo "What is the real pathname for $base/some/dubious/file?" > name
)
for name in \
$base/some/dubious/file \
$base/some/doubtful/file \
$base/elsewhere/confused/mischief/file \
$base/elsewhere/confused/where/file
do
if realpath $name
then cat $(realpath -s $name)
fi
done
Свяжитесь со мной, если Вы хотите источник для 'realpath' или 'linkpath' программы (см. мой профиль);. 'realpath' программа не является аэрокосмическими исследованиями, хотя - это в основном звонит realpath()
для каждого аргумента это дано. Существует значительно больше усилия, вовлеченного в анализ полного набора ссылок.
Я действительно не знаю об утилите. Можно написать сценарий его довольно легко. Добавление некоторой статистики или вывода ls могло бы получить Вас остальная часть пути.
#!/bin/sh
level=0
file=$1
while [ -h "$file" ]
do
previous="$file"
file=`readlink "$file"`
level=$(($level+1))
echo "$level". "$previous -> $file"
done
Используя это на нескольких ссылках, настроенных в моем homedir, я добираюсь:
$ ./test.sh link2
1. link2 -> link1
2. link1 -> Test.java