Contents

将两个字符串连接起来以在Linux中构建完整的路径

1. 概述

在本教程中,我们将通过连接两个包含子路径的字符串来检查一些构建完整 Linux 路径的方法。

首先,我们将检查一些基本技术来完成此操作。然后,我们将讨论一个通用解决方案,该解决方案允许处理连接路径时出现的一些特殊情况。

2. 连接字符串以构建路径

让我们首先检查一个需要连接字符串以获得完整路径的用例:

$ my_home_dir="/home/shubh/blogdemo/"
$ repo_path="tutorials/linux-bash/command-line-arguments/src/main/bash"

变量repo_path保存存储库中文件users-loop.sh的路径。因此,要获取此文件的绝对路径,我们需要连接my_home_dirrepo_path变量

让我们检查一个可能的解决方案:

$ file_path="$my_home_dir/$repo_path"
$ echo $file_path
/home/shubh/blogdemo//tutorials/linux-bash/command-line-arguments/src/main/bash

在这里,我们可以看到,变量file_path保存了文件users-loop.sh的完整路径。我们现在将通过列出 ( ls ) 文件users-loop.sh 来验证这一点。使用这个变量:

$ ls -lrt $file_path/users-loop.sh
-rw-r--r-- 1 shubh shubh 86 May  3 18:07 /home/shubh/blogdemo//tutorials/linux-bash/command-line-arguments/src/main/bash/users-loop.sh

如我们所见,我们的解决方案按预期工作。但是,请注意路径中的两个连续斜线 (.. blogdemo//tutorials .. )。

值得注意的是,根据路径名解析的 POSIX 标准 ,连续路径分隔符(即 / )等同于单个路径分隔符。让我们运行一个示例来验证这一点:

$ echo $my_home_dir
/home/shubh/blogdemo/
$ repo_base_dir="${my_home_dir}///tutorials" && echo $repo_base_dir
/home/shubh/blogdemo////tutorials
$ ls -ld  $repo_base_dir/linux-bash
drwxr-xr-x 1 shubh shubh 512 May  3 18:07 /home/shubh/blogdemo////tutorials/linux-bash

有用!多个/在 Linux 路径名中不是问题。然而,为了更好的可读性,人们可能希望去掉路径中多余的斜杠字符。我们可以使用realpath *命令来*实现:

$ ls -ld $(realpath ${repo_base_dir})/linux-bash
drwxr-xr-x 1 shubh shubh 512 May  3 18:07 /home/shubh/blogdemo/tutorials/linux-bash

这里我们得到绝对路径名,它没有额外的 / 引用。注意,我们在这里使用命令替换 来执行realpath命令,同时列出目录信息。

3. 处理特殊情况的通用解决方案

在上一节中,我们使用了该技术来连接包含 Linux 路径的字符串。但是,可能会有一些特殊情况,我们将在本节中讨论。

如果有人发出第一个参数是空白字符串或者可以使用相对路径与第一个路径字符串连接会发生什么?

让我们检查一个处理上述特殊情况的解决方案:

concatenate_paths() {
   base_path=${1}
   sub_path=${2}
   full_path="${base_path:+$base_path/}$sub_path"
   full_path=$(realpath ${full_path})
   echo $full_path
}

在这里,我们创建了一个Bash 函数 concatenate_paths,它接受要连接的两个输入字符串作为参数。

在此函数中,第一个参数存储在base_path变量中,第二个参数存储在sub_path变量中。然后,我们使用 shell 参数扩展来处理空base_path的情况:

${base_path:+$base_path/}

在上述条件下,如果base_path为 null 或未设置,则不进行任何替换。否则,base_path将替换为“ base_path /”。因此,仅当定义了base_path时,我们才将文件分隔符添加到 base_path。稍后,我们使用realpath命令来处理多个斜杠 (/) 的情况。此外,realpath命令还允许我们在连接字符串时使用相对路径。

让我们用一些例子来验证我们的代码:

$ concatenate_paths "/home/shubh//" "blogdemo//linux/"
/home/shubh/blogdemo/linux
$ concatenate_paths "/home/shubh//blogdemo/linux" "foo.bar"
/home/shubh/blogdemo/linux/foo.bar

结果符合我们的预期。现在让我们通过将第一个参数设为空白来进行测试:

$ concatenate_paths "" "/home/shubh//blogdemo/linux/foo.bar"
/home/shubh/blogdemo/linux/foo.bar
$ ls -lrt $(concatenate_paths "/home/shubh//blogdemo/linux" "foo.bar")
-rw-r--r-- 1 shubh shubh 0 May  3 21:02 /home/shubh/blogdemo/linux/foo.bar

它产生了正确的路径,我们还通过列出文件来验证这一点。现在,让我们通过给出相对路径来运行一个测试用例:

$ ls -lrt $(concatenate_paths "/home/shubh//blogdemo/" "./linux/foo.bar")
-rw-r--r-- 1 shubh shubh 0 May  3 21:02 /home/shubh/blogdemo/linux/foo.bar

在这里,我们证明了相对路径(使用点运算符)wrt。到第一个输入,输出看起来不错。让我们让我们的测试用例更复杂一些并验证一下:

$ ls -lrt $(concatenate_paths "/home/shubh//blogdemo/linux" "../linux/foo.bar")
-rw-r--r-- 1 shubh shubh 0 May  3 21:02 /home/shubh/blogdemo/linux/foo.bar

它可以无缝运行!因此,我们能够验证上面讨论的所有特殊情况。