gpt4 book ai didi

shell - 如何在没有 readlink 或 realpath 的情况下递归解析符号链接(symbolic link)?

转载 作者:行者123 更新时间:2023-12-01 09:21:56 25 4
gpt4 key购买 nike

如果readlink 脚本查找链接目标的最佳可移植(POSIX?)方法是什么?和 realpath不可用?

你愿意ls -l , 如果它以 l 开头取->后面的文字与 sed并重复直到它不再以 l 开头?

最佳答案

根据 BashFAQ #29 (它也支持 GNU 查找方法 suggested by @EugeniuRosca ):

一种广泛使用(虽然不是纯 POSIX)选项是使用 perl :

target=/path/to/symlink-name perl -le 'print readlink $ENV{target}'

如果您的符号链接(symbolic link)名称保证不包含 -> ,可以解析 ls的输出.

下面的代码结合了这两种方法:
# define the best readlink function available for this platform
if command -v readlink >/dev/null 2>/dev/null; then
# first choice: Use the real readlink command
readlink() {
command readlink -- "$@"
}
elif find . -maxdepth 0 -printf '%l' >/dev/null 2>/dev/null; then
# second choice: use GNU find
readlink() {
local ll candidate >/dev/null 2>&1 ||:
if candidate=$(find "$1" -maxdepth 0 -printf '%l') && [ "$candidate" ]; then
printf '%s\n' "$candidate"
else
printf '%s\n' "$1"
fi
}
elif command -v perl >/dev/null 2>/dev/null; then
# third choice: use perl
readlink() {
local candidate ||:
candidate=$(target=$1 perl -le 'print readlink $ENV{target}')
if [ "$candidate" ]; then
printf '%s\n' "$candidate"
else
printf '%s\n' "$1"
fi
}
else
# fourth choice: parse ls -ld
readlink() {
local ll candidate >/dev/null 2>&1 ||:
ll=$(LC_ALL=C ls -ld -- "$1" 2>/dev/null)
candidate=${ll#* -> }
if [ "$candidate" = "$ll" ]; then
printf '%s\n' "$1"
else
printf '%s\n' "$candidate"
fi
}
fi

readlink_recursive() {
local path prev_path oldwd found_recursion >/dev/null 2>&1 ||:
oldwd=$PWD; path=$1; found_recursion=0

while [ -L "$path" ] && [ "$found_recursion" = 0 ]; do
if [ "$path" != "${path%/*}" ]; then
cd -- "${path%/*}" || {
cd -- "$oldwd" ||:
echo "ERROR: Directory '${path%/*}' does not exist in '$PWD'" >&2
return 1
}
path=${PWD}/${path##*/}
fi
path=$(readlink "$path")
if [ -d "$path" ]; then
cd -- "$path"
path=$PWD
break
fi
if [ "$path" != "${path%/*}" ]; then
cd -- "${path%/*}" || {
echo "ERROR: Could not traverse from $PWD to ${path%/*}" >&2
return 1
}
path=${PWD}/${path##*/}
elif [ "$PWD" != "$oldwd" ]; then
path=${PWD}/$path
fi
for prev_path; do
if [ "$path" = "$prev_path" ]; then
found_recursion=1
break
fi
done
set -- "$path" "$@" # record path for recursion check
done

if [ "$path" != "${path%/../*}" ]; then
cd "${path%/*}" || {
echo "ERROR: Directory '${path%/*}' does not exist in $PWD" >&2
return 1
}
printf '%s\n' "$PWD/${path##*/}"
else
printf '%s\n' "$path"
fi
cd -- "$oldwd" ||:
}

关于shell - 如何在没有 readlink 或 realpath 的情况下递归解析符号链接(symbolic link)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31596363/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com