我有更大的shell脚本来处理不同的事情。
它将通过以下方式获得它自己的位置......
BASEDIR=`dirname $0`/..
BASEDIR=`(cd "$BASEDIR"; pwd)`
然后将使用BASEDIR创建其他变量,如
REPO="$BASEDIR"/repo
但问题是如果路径包含当前执行的空格,则此shell脚本不起作用。
所以问题是:是否存在解决该问题的良好解决方案?
答案 0 :(得分:7)
请务必双引号可能包含空格的内容:
BASEDIR="`dirname $0`"
BASEDIR="`(cd \"$BASEDIR\"; pwd)`"
答案 1 :(得分:5)
答案是“行情随处可见。”
如果您传入的路径中有空格,则dirname $0
将失败。
$ cat quote-test.sh
#!/bin/sh
test_dirname_noquote () {
printf 'no quotes: '
dirname $1
}
test_dirname_quote () {
printf 'quotes: '
dirname "$1"
}
test_dirname_noquote '/path/to/file with spaces/in.it'
test_dirname_quote '/path/to/file with spaces/in.it'
$ sh quote-test.sh
no quotes: usage: dirname string
quotes: /path/to/file with spaces
另外,试试这个有趣的例子
#!/bin/sh
mkdir -p /tmp/foo/bar/baz
cd /tmp/foo
ln -s bar quux
cd quux
cat >>find-me.sh<<"."
#!/bin/sh
self_dir="$(dirname $0)"
base_dir="$( (cd "$self_dir/.." ; pwd -P) )"
repo="$base_dir/repo"
printf 'self: %s\n' "$self_dir"
printf 'base: %s\n' "$base_dir"
printf 'repo: %s\n' "$repo"
.
sh find-me.sh
rm -rf /tmp/foo
运行时的结果:
$ sh example.sh
self: .
base: /tmp/foo
repo: /tmp/foo/repo
答案 2 :(得分:2)
引用你的完整变量:
REPO="$BASEDIR/repo"
答案 3 :(得分:2)
没有可靠和/或可移植的方法来正确执行此操作。
请参阅 How do I determine the location of my script? 了解原因
最佳答案如下,仍然依赖于操作系统
BASEDIR=$(readlink -f $0)
然后您可以执行REPO="$BASEDIR"/repo
之类的操作,只需确保引用您的变量。
答案 4 :(得分:1)
对我来说效果很好。你是如何使用REPO
的?什么具体“对你不起作用?”
我测试了
#!/bin/sh
BASEDIR=`dirname $0`/..
BASEDIR=`(cd "$BASEDIR"; pwd)`
REPO="$BASEDIR"/repo
echo $REPO
在“... / a b / c d”目录中。它按预期输出".../a b/repo"
。
请提供您收到的具体错误...“无效”错误报告是最不实用的错误报告,每个程序员都非常讨厌它。
答案 5 :(得分:1)
在unix中使用目录名中的空格总是一个问题,所以如果可以通过使用下划线来避免它们,这可以防止许多奇怪的脚本行为。
我不清楚你为什么要将BASEDIR设置为包含当前脚本(..)的目录的父目录,然后在更改到该目录后重置它
如果目录的路径有..
,它仍然可以工作e.g。 /家庭/特雷弗/数据/../回购
BASEDIR=`dirname $0`/..
我认为如果你回显$ REPO它应该正确分配路径,因为你在分配它时使用了引号但是如果你然后尝试在脚本中的其他地方使用$ REPO,那么你也需要使用双引号
e.g。
#!/bin/ksh
BASEDIR=`dirname $0`/..
$REPO="$BASEDIR"/repo
if [ ! -d ["$REPO"]
then
echo "$REPO does not exist!"
fi
答案 6 :(得分:1)
使用如下语音标记:
BASEDIR=`dirname "${0}"`/..