2008-10-28 194 views

回答

399

在bash,你应该得到你所需要的是这样的:

#!/usr/bin/env bash 

BASEDIR=$(dirname "$0") 
echo "$BASEDIR" 
+40

如果脚本在您的路径中,这将不起作用。 – 2009-08-20 19:14:40

+8

如果您已通过不同目录中的符号链接调用脚本,则这不起作用。为了完成这项工作,你还需要使用`readlink`(参见下面的答案) – AndrewR 2010-03-17 23:26:16

35

假设你正在使用bash

#!/bin/bash 

current_dir=$(pwd) 
script_dir=$(dirname $0) 

echo $current_dir 
echo $script_dir 

该脚本应该打印你的目录,然后脚本所在的目录。例如,使用/home/mez/中的脚本从/调用它时,它输出

/ 
/home/mez 

请记住,从命令的输出分配变量时,请将命令包装在$()中 - 否则您将无法获得所需的输出。

-3

这应该做的伎俩:

echo `pwd`/`dirname $0` 

它看起来难看取决于它是如何调用和CWD,但应该给你,你需要去(或者你可以,如果你关心如何调整字符串它看起来)。

302

原始文章包含解决方案(忽略响应,他们没有添加任何有用的东西)。有趣的工作是通过提到的unix命令readlink和选项-f完成的。当脚本被绝对以及相对路径调用时起作用。

对于bash,SH,KSH:

#!/bin/bash 
# Absolute path to this script, e.g. /home/user/bin/foo.sh 
SCRIPT=$(readlink -f "$0") 
# Absolute path this script is in, thus /home/user/bin 
SCRIPTPATH=$(dirname "$SCRIPT") 
echo $SCRIPTPATH 

对于tcsh,CSH:

#!/bin/tcsh 
# Absolute path to this script, e.g. /home/user/bin/foo.csh 
set SCRIPT=`readlink -f "$0"` 
# Absolute path this script is in, thus /home/user/bin 
set SCRIPTPATH=`dirname "$SCRIPT"` 
echo $SCRIPTPATH 

参见:https://stackoverflow.com/a/246128/59087

+0

这是最好的方法。请注意,如果您执行以下操作,'checked'回答将不起作用:./myscript.sh ...会报告该目录为“。”。 - 这将永远给你绝对路径 – EdH 2011-01-23 21:19:45

+9

注意:并非所有的系统都有`readlink`。这就是为什么我建议使用pushd/popd(内置bash)。 – 2011-05-20 14:29:26

+1

常用的系统没有readlink? – 2012-03-12 02:21:44

30

如果你正在使用bash ....

#!/bin/bash 

pushd $(dirname "${0}") > /dev/null 
basedir=$(pwd -L) 
# Use "pwd -P" for the path without links. man bash for more info. 
popd > /dev/null 

echo "${basedir}" 
+3

你可以用`cd $(dirname“$ {0}”)`和`cd -`替换`pushd` /`popd`,以使它在其他shell上工作,如果它们有`pwd -L`。 – 2011-05-20 14:30:42

11
cd $(dirname $(readlink -f $0)) 
12

由于theMarko提示:

BASEDIR=$(dirname $0) 
echo $BASEDIR 

这个工作,除非你从哪里脚本所在的同一目录,在这种情况下,你得到的值执行脚本“”

要解决这个问题,使用:

current_dir=$(pwd) 
script_dir=$(dirname $0) 

if [ $script_dir = '.' ] 
then 
script_dir="$current_dir" 
fi 

现在,您可以使用变量current_dir整个脚本来引用脚本目录。但是,这可能仍然存在符号链接问题。

31

在回答一个较早的评论说,它的启发,但它很容易在所有其他的答案中错过。

当使用bash:

echo this file: $BASH_SOURCE 
echo this dir: `dirname $BASH_SOURCE` 

Bash Reference Manual, 5.2 Bash Variables

3

对这个问题的最好答案在这里回答:
Getting the source directory of a Bash script from within

并且是:

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 

一个班轮,这将给你的完整目录名该脚本无论在哪里被调用。

要了解它是如何运作的,你可以执行以下脚本:

#!/bin/bash 

SOURCE="${BASH_SOURCE[0]}" 
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink 
    TARGET="$(readlink "$SOURCE")" 
    if [[ $TARGET == /* ]]; then 
    echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'" 
    SOURCE="$TARGET" 
    else 
    DIR="$(dirname "$SOURCE")" 
    echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')" 
    SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located 
    fi 
done 
echo "SOURCE is '$SOURCE'" 
RDIR="$(dirname "$SOURCE")" 
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" 
if [ "$DIR" != "$RDIR" ]; then 
    echo "DIR '$RDIR' resolves to '$DIR'" 
fi 
echo "DIR is '$DIR'" 
2

所以很多答案,所有合理的,每个职业的和反对的&略有differeing目标(这也许应该为每予以说明)。这是另一个解决方案,它可以满足所有系统中清除和工作的主要目标(在任何bash版本中没有任何假设),并且合理地执行你期望发生的事情(例如,解析符号链接是一个有趣的问题,但通常不是你真正想要的),处理边缘情况,如路径中的空格等,忽略任何错误,并且如果存在任何问题,则使用理智的默认值。

每个组件都存储在一个单独的变量,你可以单独使用:

# script path, filename, directory 
PROG_PATH=${BASH_SOURCE[0]}  # this script's name 
PROG_NAME=${PROG_PATH##*/}  # basename of script (strip path) 
PROG_DIR="$(cd "$(dirname "${PROG_PATH:-$PWD}")" 2>/dev/null 1>&2 && pwd)"