bash - 如何获得完整的路径,*允许*符号链接
问题描述
我编写了接受目录名称作为参数的 bash 脚本。一个点 ('.') 是一个有效的目录名,但我有时需要知道 '.' 在哪里 是。readlink
and命令提供了一个解析的realpath
路径,这没有帮助,因为我需要允许符号链接。
例如,给定目录的解析路径可能类似于/mnt/vol_01/and/then/some
,而脚本以 '.' 调用。在哪里 '。' 是/app/then/some
(一个符号链接,可以解析到我给出的第一条路径)。
我为解决我的问题所做的就是使用cd
和pwd
组合来提供我想要的完整路径,到目前为止它似乎运行良好。
脚本的简化示例:
DEST_DIR=$1
# Convert the given destination directory to a full path, ALLOWING
# for symbolic links. This is necessary in cases where '.' is
# given as the destination directory.
DEST_DIR=$(cd $DEST_DIR && pwd -L)
# Do stuff in $DEST_DIR
我的问题是:是我使用cd
和pwd
获得我想要的东西的最佳方式吗?或者,还有更好的方法?
解决方案
如果您要做的只是创建一个相对路径更改最小的绝对路径,那么一个简单、安全且快速的方法是:
[[ $dest_dir == /* ]] || dest_dir=$PWD/$dest_dir
(请参阅正确的 Bash 和 shell 脚本变量大写,了解为什么dest_dir
比 . 更可取DEST_DIR
。)
即使目录不存在(尚)或不可能cd
(例如,因为它的权限不允许),上面的代码也将起作用。它可能会产生带有冗余 '.' 的路径。组件、'..' 组件和多余的斜杠(`/a//b'、'//a/b/'、...)。
如果您想要一个最少清理的路径(使符号链接未解析),那么原始代码的修改版本可能是一个合理的选择:
dest_dir=$(cd -- "$dest_dir"/ && pwd)
- 处理以“-”开头的
--
目录名是必需的。 - 中的引号
"$dest_dir"
是处理包含空格(实际上是$IFS
字符)或全局字符的名称所必需的。 - 结尾的斜杠
"$dest_dir"/
对于处理相对名称为 simple 的目录是必需的-
。 - Plain
pwd
就足够了,因为它的行为就像-L
是默认指定的一样。
请注意,如果失败,代码将设置dest_dir
为空字符串。cd
您可能想在对变量执行任何其他操作之前检查这一点。
另请注意,这$(cd ...)
将使用 Bash 创建一个子 shell。这在一方面是好的,因为之后不需要cd
回到起始目录(这可能是不可能的),但如果你经常这样做(例如在循环中),它可能会导致性能问题。
最后,请注意,如果目录名称包含一个或多个尾随换行符(例如由 创建的),则代码将不起作用mkdir $'dir\n'
。有可能解决这个问题(如果你真的关心它),但它很混乱。请参阅如何避免 bash 命令替换以删除换行符?和shell:在命令替换中保留尾随换行符 ('\n')。一种可能的方法是:
dest_dir=$(cd -- "$dest_dir"/ && printf '%s.' "$PWD") # Add a trailing '.'
dest_dir=${dest_dir%.} # Remove the trailing '.'
推荐阅读
- amazon-web-services - 如何使用 EC2 上的配置文件访问 S3?(sts.amazonaws.com:443 错误)
- python - 找出列表和集合之间的区别
- python - /cart/update-transaction/0cqydz1f/ 处的 IntegrityError
- python - 我需要从漂亮的 json 创建输出
- vulkan - Vulkan的执行模型和同步
- keras - 为 Keras Fit Generator 函数中使用的验证数据设置 Training 为 False
- mysql - 在不使用 .raw 的情况下在 Knex.js 中选择一个总和
- r - 通过布尔数据框过滤数据框以插入 NA
- maven - 如何在 Docker 中从系统路径添加 jars
- r - 如何在R中重复观察n次?