$ ./ 应用
-
92 如果存在任何解决方案,则当前的解决方案都不起作用 目录名末尾的换行 -它们将被替换命令删除。 要解决此问题,可以在命令替换中附加一个非换行符- DIR=“$(cd”$(目录名“${BASH_SOURCE[0]}”)“&&pwd&&echo x)” -并在不替换命令的情况下删除它- DIR=“${DIR%x}” . – 10亿 评论 2012年9月24日12:15 -
97 @jpmc26有两种非常常见的情况:事故和破坏。 脚本不应该仅仅因为某人在某处执行了 mkdir$“\n” . – 10亿 评论 2013年3月28日8:14 -
38 任何让人们以这种方式破坏他们的系统的人都不应该让它去检测这样的问题。。。 更不用说雇佣有能力犯这种错误的人了。 在使用bash的25年里,我从未见过这种事情在任何地方发生。。。。 这就是为什么我们有像perl这样的东西和像污点检查这样的实践(我可能会因为这样说而感到愤怒:) – 奥西里斯哥特拉 评论 2015年2月5日0:12 -
86 我强烈建议读这篇文章 Bash常见问题 关于主题。 – 拉尼·阿尔贝格·温 评论 2016年1月30日2:22 -
@osirisgothra任何人如果认为解决文件名中的危险字符的方法不是编写健壮的脚本,而是阻止人们(可能在某些时候创建危险名称)访问系统,那将是很困难的。 – 街童 评论 5月3日4:15
77个答案
#!/ usr/bin/env bash(usr/bin/env bash) SCRIPT_DIR=$(cd--“$(目录名--”${BASH_SOURCE[0]}“)”&>/dev/null&&pwd)
#!/ usr/bin/env-bash SOURCE=${BASH_SOURCE[0]} 而[-L“$SOURCE”]; 执行#resolve$SOURCE操作,直到文件不再是符号链接 DIR=$(cd-P“$(目录名”$SOURCE“)”>/dev/null 2>&1&pwd) SOURCE=$(readlink“$SOURCE”) [[$SOURCE!=/*]]&&SOURCE=$DIR/$SOURCE#如果$SOUREC是相对符号链接,则需要相对于符号链接文件所在的路径进行解析 完成 DIR=$(cd-P“$(目录名”$SOURCE“)”>/dev/null 2>&1&pwd)
#!/ usr/bin/env-bash SOURCE=${BASH_SOURCE[0]} 而[-L“$SOURCE”]; 执行#resolve$SOURCE操作,直到文件不再是符号链接 目标=$(readlink“$SOURCE”) 如果[[$TARGET==/*]]; 然后 echo“SOURCE“$SOURCE”是到“$TARGET”的绝对符号链接” SOURCE=$目标 其他的 DIR=$(目录名“$SOURCE”) echo“SOURCE“$SOURCE”是到“$TARGET”的相对符号链接(相对于“$DIR”)” SOURCE=$DIR/$TARGET#如果$SOURCE是相对符号链接,我们需要相对于符号链接文件所在的路径来解析它 fi(菲涅耳) 完成 echo“SOURCE是‘$SOURCE’” RDIR=$(目录名“$SOURCE”) DIR=$(cd-P“$(目录名“$SOURCE”)”>/dev/null 2>1&&pwd) 如果[“$DIR”!=“$RDIR”]; 然后 echo“DIR'$RDIR'解析为'$DIR'” fi(菲涅耳) echo“DIR是'$DIR'”
来源”/ “scriptdir.sh”是与“sym2/scriptdir.ch”相对的符号链接(相对于“.”) SOURCE为“/ sym2/scriptdir.sh’ 方向/ sym2'解析为“/home/ubuntu/dotfiles/fo/real/real1/real2” DIR是“/home/ubuntu/dotfiles/fo fo/real/real1/real2”
-
39 您可以将此方法与用户25866的答案结合起来,得出一个适用于的解决方案 源<脚本> 和 bash<脚本> : DIR=“$(cd-P”$(目录名“${BASH_SOURCE[0]}”)“&&pwd)” . – 丹·莫尔丁 评论 2011年10月19日15:54 -
25 有时 光盘 把东西打印到STDOUT! 例如,如果您的 $CDPATH(美元) 有 . 。要覆盖此情况,请使用 DIR=“$(cd”$(目录名“${BASH_SOURCE[0]}”)“>/dev/null&&pwd)” – 用户716468 评论 2013年2月3日2:33 -
255 这个公认的答案是不好的,它不适用于符号链接,并且过于复杂。 目录名$(readlink-f$0) 是正确的命令。 请参见 gist.github.com/tvlooy/cbfbdb111a4ebad8b93e 用于测试用例 评论 2015年6月9日19:32 -
214 @tvlooy IMO你的答案也不完全正确,因为当路径中有空格时,它会失败。 与换行符相比,这种情况并不罕见。 目录名“$(readlink-f”$0“)” 不会增加复杂性,而且公平地说,对于最少的麻烦来说,它更健壮。 – 阿德里安·古恩特 评论 2015年10月28日23:38 -
20 @电视台 目录名“$(readlink-f”$0“)” 尽管在脚本来源的情况下失败,例如: /bin/bash-c。 脚本.sh …使用 $(目录名“$(readlink-f”${BASH_SOURCE[0]}“)”) 相反 – 德库马拉 评论 2022年4月18日4:12
#!/ usr/bin/env-bash echo“您正在运行的脚本有:” echo“basename:[$(basename“$0”)]” echo“目录名:[$(目录名“$0”)]” echo“密码:[$(密码)]”
[~]美元普华永道 /主页/哑光 [~]$ ./ 试验.sh 您正在运行的脚本具有: 基本名称:[test.sh] 目录名:[/home/matt] 密码:[/home/matt] [~]美元cd/tmp [~/tmp]$~/test.sh 您正在运行的脚本具有: 基本名称:[test.sh] 目录名:[/home/matt] 密码:[/tmp]
-
35 -
14 -
126 -
51 +1,但使用时的问题 目录名$0 如果目录是当前目录,您将得到 . 。这很好,除非您要更改脚本中的目录并期望使用从中获得的路径 目录名$0 好像这是绝对的。 要获得绝对路径: pushd `dirname$0`>/dev/null , SCRIPTPATH=`pwd` , popd>/dev/null : 馅饼.org/1489386 (但是 当然 有更好的方法来扩展这条路径吗?) – T.J.克劳德 评论 2011年1月23日10:30 -
13 @T。 J.克劳德我不确定 目录名$0 如果您将其分配给一个变量,然后使用它启动一个类似于 $目录/脚本.sh ; 我可以想象,90%的时间里,这就是这种类型事情的用例。 ./script.sh 会很好的。 – 亚光b 评论 2011年1月24日12:55
目录名--“$0”;
目录名--“$(readlink-f--”$0“;)”;
#!/ usr/bin/env-bash echo“密码:`pwd`” echo“\$0:$0” echo“basename:`basename--”$0“`” echo“目录名:`dirname--”$0“`” echo“目录名/readlink:$(目录名--“$(readlink-f--”$0“;)”;)”
>>>$ ./ 什么事 密码:/Users/phatblat $0: ./ 什么事 基本名称:whatdir.sh 目录名:。 目录名/readlink:/Users/phatblat
>>>$/Users/phatblat/whatdir.sh 密码:/Users/phatblat $0:/Users/phatblat/whatdir.sh 基本名称:whatdir.sh 目录名:/Users/phatblat 目录名/readlink:/Users/phatblat
>>>美元cd/tmp >>>$~/whatdir.sh美元 密码:/tmp $0:/Users/phatblat/whatdir.sh 基本名称:whatdir.sh 目录名:/Users/phatblat 目录名/readlink:/Users/phatblat
>>>$ln-s~/whatdir.sh whatdirlink.sh >>>$ ./ 什么dirlink.sh 密码:/tmp $0: ./ 什么dirlink.sh 基本名称:whatdirlink.sh 目录名:。 目录名/readlink:/Users/phatblat
>>>美元cd/tmp >>>$ . ~/ 什么事 密码:/tmp 0美元:猛击 基本名称:bash 目录名:。 目录名/readlink:/tmp
-
20 -
55 -
16 -
12 在OSX中,有 格雷德林克 ,基本上是 readlink(读链接) 我们都很熟悉。 以下是一个独立于平台的版本: dir=`greadlink-f${BASH_SOURCE[0]}||readlink-f${BAS_SOURCE[0]}` – 罗伯特 评论 2016年1月14日20:16 -
9
pushd.>”(推送>)/ dev/null'; SCRIPT_PATH=“${BASH_SOURCE[0]:-$0}”; 而[-h“$SCRIPT_PATH”]; 做 cd“$(目录名--”$SCRIPT_PATH“;)”; SCRIPT_PATH=“$(readlink-f--”$SCRIPT-PATH“;)”; 完成 cd“$(目录名--”$SCRIPT_PATH“;)”>'/dev/null'; SCRIPT_PATH=“$(pwd;)”; popd>“/dev/null”;
当通过多深度软链接调用时, 当归档时 当命令调用脚本时“ 来源 “又名 . (点)运算符。 当arg $0 从调用方修改。 “./script” “/full/path/to/script” “/some/path/../../ather/path/script” “./some/folder/script”
pushd.>”(推送>)/ dev/null'; SCRIPT_PATH=“${BASH_SOURCE[0]:-$0}”; 而[-h“$SCRIPT_PATH”]; 做 cd“$(目录名--”$SCRIPT_PATH“;)”; SCRIPT_PATH=“$(readlink-f--”$SCRIPT-PATH“;)”; 完成 cd“$(目录名--”$SCRIPT_PATH“;)”>'/dev/null'; SCRIPT_PATH=“$(pwd;)”; popd>“/dev/null”;
DIR=“$(目录名--”${BASH_SOURCE[0]}“;)”;# 获取目录名 DIR=“$(realpath-e--”$DIR“;)”;# 如果需要,解析其完整路径
-
14 -
11 为什么这不是公认的答案? 使用有什么不同吗 真实路径 通过循环“手动”解决 readlink(读链接) ? 即使是 readlink(读链接) 手册页上说 注意,realpath(1)是用于规范化功能的首选命令。 – 用户9123 评论 2020年3月25日1:14 -
6 顺便说一下,我们不应该申请 真实路径 之前 目录名 ,而不是之后? 如果脚本文件本身是符号链接。。。 它会给出如下内容 DIR=“$(目录名”$(realpath“${BASH_SOURCE[0]}”)” 。实际上非常接近西蒙提出的答案。 – 用户9123 评论 2020年3月25日1:32 -
2 @我认为接受的用户9123是尝试与所有流行的shell/distro兼容。 此外,根据您尝试执行的操作,在大多数情况下,人们希望获得符号链接所在的目录,而不是实际源的目录。 – 王 评论 2020年5月24日12:23 -
1 我的 真实路径 (和 man7.org/linux/man-pages/man1/realpath.1.html )没有 -(f) 期权; 那应该是吗 -e(电子) @维维蒂斯? (该用户添加了它。) 评论 2022年10月20日16:23
#!/ usr/bin/env-bash scriptdir=“$(目录名--”$BASH_SOURCE“;)”;
-
19 -
5 @直到,在这种情况下,我们可以使用 真实路径 命令获取的完整路径/ foo/script。 所以 目录名$(realpath./foo/script) 将给出脚本的路径。 评论 2019年12月17日5:17 -
-
24 -
-
21 -
2 @如果来源于除bash之外的任何其他shell,TimothyJones将100%失败。 ${BASH_SOURCE[0]} 一点也不令人满意。 ${BASH_SOURCE:-0} 好多了。 – 马修·卡罗夫 评论 2018年11月13日18:43 -
1
DIR=“$(目录名”$(realpath“$0”)”)“
-
10 -
6 -
三 -
1 -
2
#!/ usr/bin/env-bash reldir=“$(目录名--”$0“;)”; cd“$reldir”; 目录=“$(pwd;)”; echo“目录是${Directory}”;
cd“$(目录名--“$0”;)”;
DIR=$(cd“$(目录名”$0“)”; 密码)
./script /usr/bin/script 脚本
SELF=$(readlink/proc/$$/fd/255)
#!/ 垃圾桶/垃圾桶 目录=$(cd`dirname$0`&&pwd) echo$目录
总结:
FULL_PATH_TO_SCRIPT=“$(realpath”${BASH_SOURCE[-1]}“)” #或者,如果您不需要它也适用于**源**脚本: #FULL_PATH_TO_SCRIPT=“$(realpath“$0”)” #或者,如果是嵌套的“源”调用,则取决于所需的路径 #FULL_PATH_TO_SCRIPT=“$(实路径“${BASH_SOURCE[0]}”)” #或者,添加“-s”以不扩展路径中的符号链接: #FULL_PATH_TO_SCRIPT=“$(realpath-s”${BASH_SOURCE[-1]}“)” SCRIPT_DIRECTORY=“$(目录名“$FULL_PATH_TO_SCRIPT”)” SCRIPT_FILENAME=“$(基本名称“$FULL_PATH_TO_SCRIPT”)”
细节:
如何获得 完整文件路径 , 完整目录 ,以及 基本文件名 任何脚本 运行 或 来源 ...
#!/ 垃圾桶/垃圾桶 #A.获取完整路径,并展开(向下走)符号链接 #A.1、` “$0”仅在文件为**运行**时有效,但在文件为**source**时无效。 #FULL_PATH_TO_SCRIPT=“$(realpath“$0”)” #A.2、` “${BASH_SOURCE[-1]}”`无论文件是源文件还是运行文件,甚至 #如果脚本是从另一个bash函数中调用的! #注意:如果`“${BASH_SOURCE[-1]}”`不能满足您的要求,请使用 #改为`“${BASH_SOURCE[0]}”`,以便从数组中获取第一个元素。 FULL_PATH_TO_SCRIPT=“$(实路径“${BASH_SOURCE[-1]}”)” #B.1、` “$0”`仅在文件为**运行**时有效,但在文件为**来源**时无效。 #FULL_PATH_TO_SCRIPT_KEEP_SYMLINKS=“$(realpath-s”$0“)” #B.2节` “${BASH_SOURCE[-1]}”`无论文件是源文件还是运行文件,甚至 #如果脚本是从另一个bash函数中调用的! #注意:如果`“${BASH_SOURCE[-1]}”`不能满足您的要求,请使用 #取而代之的是`“${BASH_SOURCE[0]}”`,以便从数组中获取第一个元素。 FULL_PATH_TO_SCRIPT_KEEP_SYMLINKS=“$(realpath-s”${BASH_SOURCE[-1]}“)” #然后还可以获得目录的完整路径和基 #文件名,如下所示: SCRIPT_DIRECTORY=“$(目录名“$FULL_PATH_TO_SCRIPT”)” SCRIPT_FILENAME=“$(基本名称“$FULL_PATH_TO_SCRIPT”)” #现在打印出来 echo“FULL_PATH_TO_SCRIPT=\”$FULL_PATH_TO_SCRIPT\“” echo“SCRIPT_DIRECTORY=\”$SCRIPT_DIRECTORY\“” echo“SCRIPT_FILENAME=\”$SCRIPT-FILENAME\“”
正在运行 脚本: ~/GS/dev/eRCaGuy_hello_world/bash$/ 获取脚本路径.sh FULL_PATH_TO_SCRIPT=“/home/gabriel/GS/dev/eRCaGuy_hello_world/bash/get_SCRIPT_PATH.sh” SCRIPT_DIRECTORY=“/home/gabriel/GS/dev/eRCaGuy_hello_world/bash” SCRIPT_FILENAME=“获取脚本路径.sh” 采购 带有的脚本 .获取脚本路径.sh 或 源get_script_path.sh (结果与上面的完全相同,因为我使用了 “${BASH_SOURCE[-1]}” 在脚本中,而不是 "$0" ): ~/GS/dev/eRCaGuy_hello_world/bash$。 获取脚本路径.sh FULL_PATH_TO_SCRIPT=“/home/gabriel/GS/dev/eRCaGuy_hello_world/bash/get_SCRIPT_PATH.sh” SCRIPT_DIRECTORY=“/home/gabriel/GS/dev/eRCaGuy_hello_world/bash” SCRIPT_FILENAME=“获取脚本路径.sh”
~/GS/dev/eRCaGuy_hello_world/bash$。 获取脚本路径.sh FULL_PATH_TO_SCRIPT=“/bin/bash” SCRIPT_DIRECTORY=“/bin” SCRIPT_FILENAME=“猛击”
#获取完整路径,但不要展开(向下走)符号链接; 在里面 #换句话说:保留符号链接作为路径的一部分! FULL_PATH_TO_SCRIPT=“$(realpath-s”${BASH_SOURCE[-1]}“)”
参考文献:
如何检索给定相对路径的绝对路径 教会了我 BASH_源 变量: Unix和Linux:确定源shell脚本的路径 教我的 BASH_源 实际上是一个数组,我们希望它的最后一个元素能在函数中按预期工作(因此我使用 “${BASH_SOURCE[-1]}” 在我的代码中): Unix和Linux:确定源shell脚本的路径 bash手册 -->搜索 BASH_源 : BASH_源 一个数组变量,其成员是源文件名,其中 姓名 数组变量已定义。 shell函数 ${函数名[$i]} 在文件中定义 ${BASH_SOURCE[$i]} 并从呼叫 ${BASH_SOURCE[$i+1]} .
另请参见:
我对Python的回答是: 如何获取当前正在执行的python文件的路径和名称? [我的回答] Unix和Linux:确定源shell脚本的路径
-
2 两者的区别是什么 ${BASH_SOURCE[-1]} 和 ${BASH_SOURCE[0]} ? 我知道 -1 从数组中检索最后一个元素,并 0 检索第一个,但在哪种情况下,我要使用一个而不是另一个? – 伊利·G。 评论 2022年4月13日14:26 -
-
@伊利·G。, 我想是的。而且,我没有尝试,但就我而言,我认为索引 1 会给我同样的结果 -1 因为我认为数组中只有2个元素,所以这在两种情况下都是最后一个元素。 评论 2022年4月13日15:56
real=$(realpath“$(目录名“$0”)”)
-
1 -
7 -
5 在Linux上,realpath是一个标准实用程序(GNU coreutils包的一部分),但它不是bash内置的(即bash本身提供的函数)。 如果您正在运行Linux,此方法可能会起作用,尽管我会将 $0 对于 ${BASH_SOURCE[0]} 这样,该方法可以在任何地方工作,包括在函数中。 – 德·理查森 评论 2014年7月18日15:53 -
5 这个答案中的操作顺序是错误的。 你需要 第一 解析符号链接, 然后 做 目录名 因为的最后一部分 $0 可能是指向与符号链接本身不在同一目录中的文件的符号链接。 这个答案中描述的解决方案只获取它存储符号链接的目录的路径,而不是目标的目录。 此外,此解决方案缺少引用。 如果路径包含特殊字符,它将不起作用。 – 哈杰罗 评论 2015年4月13日21:43 -
4
actual_path=$(readlink-f“${BASH_SOURCE[0]}”) script_dir=$(目录名“$actual_path”)
${BASH_SOURCE[0]} -脚本的完整路径。 即使脚本是源代码,此值也将是正确的,例如。 源<(echo“echo$0”) 打印 猛击 ,同时将其替换为 ${BASH_SOURCE[0]} 将打印脚本的完整路径。 (当然,这假设您可以依赖Bash。) readlink-f -递归解析指定路径中的任何符号链接。 这是一个GNU扩展,在(例如)BSD系统上不可用。 如果你正在运行Mac,你可以使用Homebrew安装GNU coreutils公司 并用 greadlink-f . 当然了 目录名 获取路径的父目录。
/var/没人/思考/关于空间存在/在目录中/名称/这是你的文件。text
#!/ 垃圾桶/垃圾桶 echo“密码:`pwd`” echo“\$0:$0” echo“basename:`basename”$0“`” echo“目录名:`dirname”$0“`”
cd“`dirname”$0“`”
SCRIPT_DIR=“” pushd“$(目录名”$(readlink-f“$BASH_SOURCE”)”)“>/dev/null&&{ SCRIPT_DIR=“$PWD” popd>/dev/null }
-
-
1 更好 SCRIPT_DIR=“”; pushd“$(目录名”$(readlink-f“$BASH_SOURCE”)”)“>/dev/null&&{SCRIPT_DIR=$PWD;popd>/devnull;} 评论 2014年7月3日4:15 -
@konsolebox,你想防御什么? 我通常喜欢内联逻辑条件,但您在pushd中看到的具体错误是什么? 我宁愿找到一种直接处理它的方法,而不是返回空的SCRIPT_DIR。 – Fuwjax公司 评论 2015年1月19日20:03 -
@Fuwjax避免这样做的自然实践 邻苯二胺 在以下情况下(即使很少) 推送的 失败。 万一 推送的 失败了,你认为它的价值是什么 脚本_DIR ? 操作可能会有所不同,这取决于看起来合乎逻辑的内容或用户可能喜欢的内容,但肯定是这样做的 邻苯二胺 是错误的。 评论 2015年1月20日19:21 -
#检索被调用脚本的完整路径名 scriptPath=$(其中$0) #检查路径是否为链接 如果[-L$scriptPath]; 然后 #它是一个链接,然后检索目标路径并获取目录名 sourceDir=$(目录名$(readlink-f$scriptPath)) 其他的 #否则,只需获取脚本路径的目录名 sourceDir=$(目录名$scriptPath) fi(菲涅耳)
#!/ 垃圾桶/垃圾桶 # the_source=$(readlink-f${BASH_source[0]}) dirname=$(目录名${thesource}) echo“the_source:${the_source}” echo“用户名:${用户名}”
用户@计算机 :~/下载/temp$/ 试验.sh
the_source:/home/user/Downloads/temp/test.sh 目录名:/home/user/Downloads/temp
脚本:“/tmp/src-dir/test.sh” 调用文件夹:“/tmp/src-dir/other”
echo Script-Dir:`dirname“$(realpath$0)”` echo脚本目录:$(cd${0%/*}&&pwd-P) echo脚本目录:$(目录名“$(readlink-f“$0”)) 回声 echo脚本名称:`basename“$(realpath$0)”` echo脚本名称:`basename$0` 回声 echo Script-Dir-Relative:`目录名“$BASH_SOURCE”` echo Script-Dir-Relative:`dirname$0` 回声 echo Calling-Dir:`pwd`
脚本目录:/tmp/src-Dir 脚本目录:/tmp/src-Dir 脚本目录:/tmp/src-Dir 脚本名称:test.sh 脚本名称:test.sh 脚本无关:。。 脚本无关:。。 调用目录:/tmp/src-Dir/other
路径=“$(目录名”$(其中“$0”)”)“
源“$(目录名”$(其中“$0”)”)/lib/B
-
5 上的点 哪一个 很有争议。 类型 , 搞砸 和其他内置程序在bash中做同样的事情更好。 哪一个 更便于携带,尽管它实际上并不一样 哪一个 在tcsh等其他shell中使用,它是一个内置程序。 评论 2014年1月13日22:30 -
2
绝对路径或相对路径 文件和目录软链接 调用为 脚本 , bash脚本 , bash-c脚本 , 源脚本 ,或 .script脚本 目录和/或文件名中的空格、制表符、换行符、Unicode等 以连字符开头的文件名
解析=“$(readlink/proc/$$/fd/255&&echo X)”&&resolved=“${resolved%$'\nX'}”
绝对路径=$(readlink-e--“${BASH_SOURCE[0]}”&&echo x)&&absolute_path=${绝对路径%?x} dir=$(目录名--“$absolute_path”&&echo x)&&dir=${dir%?x} file=$(basename--“$absolute_path”&&echo x)&&file=${file%?x} ls-l--“$dir/$file” printf'$absolute_path:“%s”\n'“$absolte_path”
CWD=“$(cd-P--”$(目录名--“${BASH_SOURCE[0]}”)“&&pwd-P)”
realpath(){ [[$1=/*]]&&回声“$1”||echo“$PWD/${1#./}” }