我编写了bash脚本,这些脚本接受目录名称作为参数。单点('。')是有效的目录名称,但是有时我需要知道'。'在哪里。是。 readlink
和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
是获得我想要的东西的最好方法吗?还是有更好的方法?
答案 0 :(得分:1)
如果您要做的就是创建一条相对路径,该相对路径的变化最小,那么一种简单,安全,快速的方法就是:
[[ $dest_dir == /* ]] || dest_dir=$PWD/$dest_dir
(请参见Correct Bash and shell script variable capitalization,以了解为什么dest_dir
比DEST_DIR
更可取。)
即使该目录不存在(或者尚未)或无法cd
(例如,由于其权限不允许),上述代码也可以使用。它可能会产生带有冗余“。”的路径。组件,“ ..”组件和多余的斜杠(“ / a // b”,“ // a / b /”、...)。
如果您想要一个最小限度的清理路径(不解决符号链接),那么修改原始代码可能是一个合理的选择:
dest_dir=$(cd -- "$dest_dir"/ && pwd)
--
对于处理以'-'开头的目录名是必需的。"$dest_dir"
中的引号来处理包含空格(实际上是$IFS
个字符)或glob字符的名称。"$dest_dir"/
的目录,必须在-
后面加上斜杠。pwd
就足够了,因为它的行为就像默认情况下指定了-L
。请注意,如果dest_dir
失败,则代码会将cd
设置为空字符串。您可能要先检查该变量,然后再对该变量进行其他操作。
还要注意$(cd ...)
将使用Bash创建一个子shell。这在某种意义上是好的,因为之后不需要cd
回到起始目录(这可能是不可能的),但是如果您做很多(例如循环),可能会导致性能问题。 / p>
最后,请注意,如果目录名称包含一个或多个结尾的换行符(例如,由mkdir $'dir\n'
创建的代码),则该代码将无效。可以解决问题(以防万一,您真的很在意),但这很麻烦。请参见How to avoid bash command substitution to remove the newline character?和shell: keep trailing newlines ('\n') in command substitution。一种可行的方法是:
dest_dir=$(cd -- "$dest_dir"/ && printf '%s.' "$PWD") # Add a trailing '.'
dest_dir=${dest_dir%.} # Remove the trailing '.'