在Linux上,readlink实用程序接受附加链接后面的选项-f。这似乎不适用于Mac和基于BSD的系统。等价的是什么?
下面是一些调试信息:
$ which readlink; readlink -f
/usr/bin/readlink
readlink: illegal option -f
usage: readlink [-n] [file ...]
在Linux上,readlink实用程序接受附加链接后面的选项-f。这似乎不适用于Mac和基于BSD的系统。等价的是什么?
下面是一些调试信息:
$ which readlink; readlink -f
/usr/bin/readlink
readlink: illegal option -f
usage: readlink [-n] [file ...]
当前回答
我已经简单地粘贴以下到我的bash脚本的顶部:
#!/usr/bin/env bash -e
declare script=$(basename "$0")
declare dirname=$(dirname "$0")
declare scriptDir
if [[ $(uname) == 'Linux' ]];then
# use readlink -f
scriptDir=$(readlink -f "$dirname")
else
# can't use readlink -f, do a pwd -P in the script directory and then switch back
if [[ "$dirname" = '.' ]];then
# don't change directory, we are already inside
scriptDir=$(pwd -P)
else
# switch to the directory and then switch back
pwd=$(pwd)
cd "$dirname"
scriptDir=$(pwd -P)
cd "$pwd"
fi
fi
并删除了readlink -f的所有实例。$scriptDir和$script将可用于脚本的其余部分。
虽然这并不适用于所有符号链接,但它适用于所有系统,并且对于大多数用例来说已经足够好了,它将目录切换到包含该目录的文件夹,然后执行pwd -P以获得该目录的实际路径,最后切换回原始目录。
其他回答
你可能对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版本应该更短。:)
Perl有一个readlink函数(例如,如何在Perl中复制符号链接?)这适用于大多数平台,包括OS X:
perl -e "print readlink '/path/to/link'"
例如:
$ mkdir -p a/b/c
$ ln -s a/b/c x
$ perl -e "print readlink 'x'"
a/b/c
我为OS X编写了一个realpath实用程序,它可以提供与readlink -f相同的结果。
这里有一个例子:
(jalcazar@mac tmp)$ ls -l a
lrwxrwxrwx 1 jalcazar jalcazar 11 8月 25 19:29 a -> /etc/passwd
(jalcazar@mac tmp)$ realpath a
/etc/passwd
如果您正在使用MacPorts,可以使用以下命令安装:sudo port selfupdate && sudo port install realpath。
我个人做了一个叫realpath的脚本,看起来有点像:
#!/usr/bin/env python
import os, sys
print(os.path.realpath(sys.argv[1]))
MacPorts和Homebrew提供了包含greadlink (GNU readlink)的coreutils包。这要归功于Michael Kallweitt在mackb.com上的帖子。
brew install coreutils
greadlink -f file.txt