我有一个脚本(~/.../gremlin),我为它创建了一个软链接:
ln -s ~/[...]/gremlin ~/sc/gremlin
~/sc/gremlin
是在$PATH
.
直接调用脚本就可以了。
通过链接调用它不会。
它使用dirname $0
所以什么也得不到。
有没有一种方法可以使此设置工作而无需更改脚本并且无需创建另一个脚本来代替软链接?
$0 的用法如下:
case `uname` in
CYGWIN*)
CP=$( echo `dirname $0`/../lib/*.jar . | sed 's/ /;/g')
;;
*)
CP=$( echo `dirname $0`/../lib/*.jar . | sed 's/ /:/g')
esac
答案1
使用是否dirname $0
有问题取决于如何它被使用了。如果没有更多细节,我们无法回答这个问题。
如果(a)的使用dirname $0
有问题并且(b)您无法更改脚本,那么解决方案就是~/sc/gremlin
用脚本替换软链接:
#!/bin/sh
exec ~/../gremlin "$@"
这样,~/../gremlin
就会以正确的方式运行$0
。
使用exec
意味着运行该脚本的进程~/../gremlin
将取代正在运行的进程~/sc/gremlin
。这比保留两个进程直到~/../gremlin
完成更有效。
答案2
如果您想~/...
从 派生目录$0
,而不是~/sc
从脚本内派生,您可以执行以下操作:
如果是zsh
脚本:
#! /bin/zsh -
dir=$0:A:h
否则,假设您有一个readlink
与 GNU 的命令类似的命令(某些系统有一个realpath
您可以使用的命令):
#! /bin/sh -
dir=$(dirname -- "$(readlink -f -- "$0")")
readlink -f
并$0:A
给你典范文件的路径,即解析所有路径组件中的所有符号链接后的绝对路径。
进而:
set -- "$dir"/../lib/*.jar .
case $(uname) in
CYGWIN*) IFS=';';;
*) IFS=:;;
esac
CP="$*"
或者:
case $(uname) in
CYGWIN*) sep=';';;
*) sep=:;;
esac
CP=$(printf "%s$sep" "$dir"/../lib/*.jar).
答案3
正如@john1024指出的,OP问题中的拼写错误可能是问题的重点:
ln -s ~/.../gremlin ~/sc/gremlin
虽然一些应用程序支持三点,但 Unix 文件系统却不支持。你的壳展开~
(波形符),而不是ln
,所以
ln -s ~/../gremlin ~/sc/gremlin
将按预期扩展路径名。如果链接已存在,您可以使用 选项覆盖它-f
。但是,如果目标是实际文件,该-f
选项将使用符号链接默默地覆盖该文件。您可能想要使用-i
至少告诉您已经存在某些内容的选项。
如果你想验证链接(证明它指向一个文件),选项-L
很有ls
用:
ls -lL ~/sc/gremlin
如果它不是文件,ls
将(取决于实现)仅显示l
类型(列表的第一个字符),带有权限位的问号),或其他一些表明它不指向真实文件的指示(在这种情况下,OSX 根本拒绝显示任何内容,尽管它会计算符号链接的总大小)。
进一步阅读:
- 三点通配符
- 使用…(三个点)引用祖父母目录的能力发生了什么?
- 4.5.1 省略号通配符(20 世纪 80 年代 VMS 的一项功能)