当前位置:  开发笔记 > 编程语言 > 正文

如何将当前工作目录设置为脚本目录?

如何解决《如何将当前工作目录设置为脚本目录?》经验,为你挑选了5个好方法。

我正在写一个bash脚本.我需要当前的工作目录始终是脚本所在的目录.

默认行为是脚本中的当前工作目录是我运行它的shell的目录,但我不想要这种行为.



1> ndim..:
#!/bin/bash
cd "$(dirname "$0")"


如果你将脚本称为`./ script`,`.`是正确的目录,并且改为`.`它也将最终出现在`script`所在的目录中,即在当前的工作目录中.
dirname返回'.' 在Windows下使用bash时.所以,保罗的答案更好.
也返回'.' 在Mac OSX中
如果你从当前目录运行脚本,就像`bash script.sh`那样,`$ 0`的值是`script.sh`.`cd`命令为你"工作"的唯一方法是因为你不关心失败的命令.如果你使用`set -o errexit`(又名:`set -e`)来确保你的脚本不会超过失败的命令,那就不行了,因为`cd script.sh`是一个错误.可靠的[bash特定]方式是`cd"$(dirname $ {BASH_SOURCE [0]})"`
值得注意的是,如果符号链接构成"$ 0"的一部分,事情就会破裂.在您的脚本中,您可能希望,例如,`../../`引用脚本位置上方两级的目录,但如果符号链接在播放中则不一定如此.
@BrunoBronosky:`dirname script.sh`打印`.`并以退出代码0退出。因此,执行了cd .`,并且退出代码为0。我不知道出现失败命令的位置。

2> 小智..:

以下也有效:

cd "${0%/*}"

语法中充分地阐述这个 StackOverflow的答案.


如果路径包含空格,请不要忘记用引号括起来.即cd"$ {0%/*}"
解释它是如何工作的:http://stackoverflow.com/questions/6393551/what-is-the-meaning-of-0-in-a-bash-script
我会说这个答案太简洁了.你几乎不了解语法.关于如何阅读这个的一些描述将是有帮助的.
如果使用`bash script.sh`调用脚本,则会失败 - "$ 0"将只是文件的名称
这个技巧也不会产生一个子壳,所以对速度怪来说也是好事.

3> kenorb..:

尝试以下简单的单行:


适用于所有UNIX/OSX/Linux

dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)

注意:命令中使用双短划线( - )表示命令选项的结束,因此包含短划线或其他特殊字符的文件不会破坏命令.


对于Linux,Mac和其他*BSD:

dir=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)

白色空间支持:

cd "$(dirname "$(realpath "$0")")";

注意:${BASH_SOURCE[0]}默认情况下应该安装在最流行的Linux发行版中(比如Ubuntu),但在某些情况下它可能会丢失,所以你必须安装它.

否则你可以尝试类似的东西(它将使用第一个现有的工具):

cd "$(dirname "$(readlink -f "$0" || realpath "$0")")"

对于Linux特定:

cd "$(dirname "$(readlink -f "$0")")"

在*BSD/Mac上使用GNU readlink:

cd "$(dirname "$(greadlink -f "$0")")"

注意:您需要$0安装(例如1.安装Homebrew,2.source).


在bash中

在bash中,您可以使用参数扩展来实现这一点,例如:

cd "${0%/*}"

但如果脚本从同一目录运行,则它不起作用.

或者,您可以在bash中定义以下函数:

realpath () {
  [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}

此函数需要1个参数.如果参数已经是绝对路径,则按原样打印,否则打印.变量+文件名参数(不带realpath前缀).

或者这是从Debian ${BASH_SOURCE[0]}文件中获取的版本:

function realpath()
{
    f=$@
    if [ -d "$f" ]; then
        base=""
        dir="$f"
    else
        base="/$(basename "$f")"
        dir=$(dirname "$f")
    fi
    dir=$(cd "$dir" && /bin/pwd)
    echo "$dir$base"
}

有关:

如何检测我运行shell脚本的当前目录?

从内部获取Bash脚本的源目录

使用OSX的Bash脚本绝对路径

bash脚本可靠的方式来获取自己的完整路径?

也可以看看:

如何在Mac上获取GNU的readlink -f的行为?


比流行的答案要好得多,因为它可以解析syslinks,并且可以解决不同的操作系统问题.谢谢!
命令中使用双短划线(` - `)来表示命令选项的结束,因此包含短划线或其他特殊字符的文件不会破坏命令.尝试例如通过`touch"-test"`和`touch - -test`创建文件,然后通过`rm"-test"`和`rm - -test`删除文件,看看差异.

4> Dan Moulding..:
cd "$(dirname "${BASH_SOURCE[0]}")"

这很简单.有用.


当脚本B来自其他脚本A并且您需要使用相对于脚本B的路径时,这非常有用.谢谢.
这也适用于**Cygwin**,对于我们这些不幸不得不触摸Windows的人来说.
或`cd“ $ {BASH_SOURCE%/ *}” || 退出

5> James McGuig..:

对于没有在其他地方进行符号链接(例如)的脚本,可接受的答案很好用$PATH

#!/bin/bash
cd "$(dirname "$0")"

但是,如果脚本是通过符号链接运行的,

ln -sv ~/project/script.sh ~/bin/; 
~/bin/script.sh

这将进入~/bin/目录,而不是~/project/目录cd ,如果的目的cd是包括相对于Windows的依赖关系,则可能会破坏脚本。~/project/

symlink安全答案如下:

#!/bin/bash
cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

readlink -f 需要解析潜在的符号链接文件的绝对路径。

需要使用引号来支持可能包含空格的文件路径(不好的做法,但不能肯定不会出现这种情况)

推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有