До 1 января 1970 года истина и ложь были наоборот ...
readlink -f
делает две вещи:
Если вы хотите, вы можете просто построить сценарий оболочки, который использует обычное поведение readlink для достижения того же результата. Вот вам пример. Очевидно, вы можете вставить это в свой собственный скрипт, где вы хотите вызвать readlink -f
#!/bin/sh
TARGET_FILE=$1
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]
do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT
Обратите внимание, что это не включает никакой обработки ошибок. Что особенно важно, он не определяет циклы символических ссылок. Простой способ сделать это - подсчитать, сколько раз вы обходите цикл и терпят неудачу, если вы набираете невероятно большое число, например 1000.
Пути к ссылке для чтения в моей и вашей системе различаются. Пожалуйста, попробуйте указать полный путь:
/ sw / sbin / readlink -f
Возможно, вас заинтересует realpath (3)
или Python os.path.realpath
. Это не совсем то же самое; вызов библиотеки C требует наличия компонентов промежуточного пути, в то время как версия Python не существует.
$ pwd
/tmp/foo
$ ls -l
total 16
-rw-r--r-- 1 miles wheel 0 Jul 11 21:08 a
lrwxr-xr-x 1 miles wheel 1 Jul 11 20:49 b -> a
lrwxr-xr-x 1 miles wheel 1 Jul 11 20:49 c -> b
$ python -c 'import os,sys;print(os.path.realpath(sys.argv[1]))' c
/private/tmp/foo/a
Я знаю, что вы сказали, что предпочитаете что-то более легкое, чем другой язык сценариев, но на всякий случай, если компиляция двоичного файла невыносима, вы можете использовать Python и ctypes (доступны в Mac OS X 10.5), чтобы обернуть вызов библиотеки:
#!/usr/bin/python
import ctypes, sys
libc = ctypes.CDLL('libc.dylib')
libc.realpath.restype = ctypes.c_char_p
libc.__error.restype = ctypes.POINTER(ctypes.c_int)
libc.strerror.restype = ctypes.c_char_p
def realpath(path):
buffer = ctypes.create_string_buffer(1024) # PATH_MAX
if libc.realpath(path, buffer):
return buffer.value
else:
errno = libc.__error().contents.value
raise OSError(errno, "%s: %s" % (libc.strerror(errno), buffer.value))
if __name__ == '__main__':
print realpath(sys.argv[1])
Как ни странно, версия C этого сценария должна быть короче. :)
Я лично создал сценарий под названием realpath, который выглядит примерно так:
#!/usr/bin/env python
import os.sys
print os.path.realpath(sys.argv[1])
Вот переносимая функция оболочки, которая должна работать в ЛЮБОЙ оболочке, сопоставимой с Борном. Она разрешит относительный путь пунктуация ".. или." и разыменование символических ссылок.
Если по какой-то причине у вас нет команды realpath (1) или readlink (1), это может быть псевдонимом.
which realpath || alias realpath='real_path'
Наслаждайтесь:
real_path () {
OIFS=$IFS
IFS='/'
for I in $1
do
# Resolve relative path punctuation.
if [ "$I" = "." ] || [ -z "$I" ]
then continue
elif [ "$I" = ".." ]
then FOO="${FOO%%/${FOO##*/}}"
continue
else FOO="${FOO}/${I}"
fi
## Resolve symbolic links
if [ -h "$FOO" ]
then
IFS=$OIFS
set `ls -l "$FOO"`
while shift ;
do
if [ "$1" = "->" ]
then FOO=$2
shift $#
break
fi
done
IFS='/'
fi
done
IFS=$OIFS
echo "$FOO"
}
также на всякий случай, если кого-то интересует, как реализовать базовое имя и имя каталога в 100% чистом коде оболочки:
## http://www.opengroup.org/onlinepubs/000095399/functions/dirname.html
# the dir name excludes the least portion behind the last slash.
dir_name () {
echo "${1%/*}"
}
## http://www.opengroup.org/onlinepubs/000095399/functions/basename.html
# the base name excludes the greatest portion in front of the last slash.
base_name () {
echo "${1##*/}"
}
Вы можете найти обновленную версию этого кода оболочки на моем сайте в Google: http://sites.google.com/site/jdisnard/realpath
РЕДАКТИРОВАТЬ: Этот код лицензирован в соответствии с условиями лицензии с двумя пунктами (стиль FreeBSD). A копию лицензии можно найти, перейдя по указанной выше гиперссылке на мой сайт.