Unix shell脚本找出脚本文件所在的目录?
在bash,你应该得到你所需要的是这样的:
#!/usr/bin/env bash
BASEDIR=$(dirname "$0")
echo "$BASEDIR"
假设你正在使用bash
#!/bin/bash
current_dir=$(pwd)
script_dir=$(dirname $0)
echo $current_dir
echo $script_dir
该脚本应该打印你的目录,然后脚本所在的目录。例如,使用/home/mez/
中的脚本从/
调用它时,它输出
/
/home/mez
请记住,从命令的输出分配变量时,请将命令包装在$(
和)
中 - 否则您将无法获得所需的输出。
这应该做的伎俩:
echo `pwd`/`dirname $0`
它看起来难看取决于它是如何调用和CWD,但应该给你,你需要去(或者你可以,如果你关心如何调整字符串它看起来)。
原始文章包含解决方案(忽略响应,他们没有添加任何有用的东西)。有趣的工作是通过提到的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
这是最好的方法。请注意,如果您执行以下操作,'checked'回答将不起作用:./myscript.sh ...会报告该目录为“。”。 - 这将永远给你绝对路径 – EdH 2011-01-23 21:19:45
注意:并非所有的系统都有`readlink`。这就是为什么我建议使用pushd/popd(内置bash)。 – 2011-05-20 14:29:26
常用的系统没有readlink? – 2012-03-12 02:21:44
如果你正在使用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}"
你可以用`cd $(dirname“$ {0}”)`和`cd -`替换`pushd` /`popd`,以使它在其他shell上工作,如果它们有`pwd -L`。 – 2011-05-20 14:30:42
cd $(dirname $(readlink -f $0))
由于theMarko提示:
BASEDIR=$(dirname $0)
echo $BASEDIR
这个工作,除非你从哪里脚本所在的同一目录,在这种情况下,你得到的值执行脚本“”
要解决这个问题,使用:
current_dir=$(pwd)
script_dir=$(dirname $0)
if [ $script_dir = '.' ]
then
script_dir="$current_dir"
fi
现在,您可以使用变量current_dir整个脚本来引用脚本目录。但是,这可能仍然存在符号链接问题。
在回答一个较早的评论说,它的启发,但它很容易在所有其他的答案中错过。
当使用bash:
echo this file: $BASH_SOURCE
echo this dir: `dirname $BASH_SOURCE`
让我们把它POSIX:
a="/$0"; a=${a%/*}; a=${a:-.}; a=${a#/}/; BASEDIR=$(cd "$a"; pwd)
测试在许多Bourne兼容shell包括BSD的。
据我所知我是作者,我把它放入公有领域。欲了解更多信息,请参阅: https://www.jasan.tk/posix/2017/05/11/posix_shell_dirname_replacement
对这个问题的最好答案在这里回答:
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'"
所以很多答案,所有合理的,每个职业的和反对的&略有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)"
如果脚本在您的路径中,这将不起作用。 – 2009-08-20 19:14:40
如果您已通过不同目录中的符号链接调用脚本,则这不起作用。为了完成这项工作,你还需要使用`readlink`(参见下面的答案) – AndrewR 2010-03-17 23:26:16