Unix shell脚本找出脚本文件所在的目录?
基本上我需要运行与脚本文件位置相关的path的脚本,我怎么能改变当前目录到脚本文件所在的目录?
在Bash中,你应该得到你需要的这样的东西:
#!/usr/bin/env bash BASEDIR=$(dirname "$0") echo "$BASEDIR"
原来的文章包含解决scheme(忽略回应,他们没有添加任何有用的东西)。 有趣的工作是由提到的unix命令readlink
和选项-f
。 当脚本被绝对以及相对path调用时起作用。
对于bash,sh,ksh:
#!/bin/bash # Absolute path to this script, eg /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, eg /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
假设你正在使用bash
#!/bin/bash current_dir=$(pwd) script_dir=$(dirname $0) echo $current_dir echo $script_dir
这个脚本在运行时应该打印你所在的目录,然后打印脚本所在的目录,例如,当从/(脚本在/ home / mez /中)调用它时,它输出
/ /home/mez
请记住,从命令的输出中分配variables时,将命令封装在$(和)中 – 否则您将无法获得所需的输出。 `
如果你使用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}"
早些时候对一个答案的评论说,但在所有其他答案中很容易错过。
当使用bash时:
echo this file: $BASH_SOURCE echo this dir: `dirname $BASH_SOURCE`
Bash参考手册,5.2 Bashvariables
正如马克所说:
BASEDIR=$(dirname $0) echo $BASEDIR
除非您从脚本所在的同一个目录执行脚本,否则您将获得“。”值。
为了解决这个问题,请使用:
current_dir=$(pwd) script_dir=$(dirname $0) if [ $script_dir = '.' ] then script_dir="$current_dir" fi
您现在可以在整个脚本中使用variablescurrent_dir来引用脚本目录。 但是,这可能仍然存在符号链接问题。
cd $(dirname $(readlink -f $0))
受到blueyed的回答启发
read < <(readlink -f $0 | xargs dirname) cd $REPLY
这个问题的最佳答案在这里得到了回答:
从内部获取Bash脚本的源代码目录
并且是:
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'"
让我们来做POSIX:
a="/$0"; a=${a%/*}; a=${a:-.}; a=${a#/}/; BASEDIR=$(cd $a; pwd)
testing了许多兼容Bourne的shell,包括BSD。
据我所知,我是作者,我把它列入公有领域。 欲了解更多信息,请参阅: https : //www.jasan.tk/posix/2017/05/11/posix_shell_dirname_replacement
这么多的答案,都是有道理的,每个都有专业人士和学生的不同目标(这些应该可以分别说明)。 这是另一个解决scheme,它符合所有系统中清除和工作的主要目标(对bash版本,或者readlink
或pwd
选项没有任何假设),并且合理地执行你期望发生的事情(例如,parsing符号链接是一个有趣的问题,但通常不是你真正想要的),处理边缘情况,如path中的空格等,忽略任何错误,如果有任何问题,使用默认的默认值。
每个组件都存储在一个单独的variables中,您可以单独使用它们:
# 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)"
这应该够了吧:
echo `pwd`/`dirname $0`
它可能看起来很丑,取决于它是如何被调用的,而且应该让你去你需要的地方(或者你可以调整string,如果你关心的话)。