Build complete path in Linux by concatenate two strings?


Overview

We’ll look at some ways to create a complete Linux path by combining two paths into one.

We’ll first look at some basic techniques for accomplishing this. Then, we'll talk about a generic approach that handles some of the special cases that appear when combining paths.

Concatenating Strings to Build a Path

We'll start by looking at an example where we want to concatenated strings to create a complete path.

$ my_home_dir="/home/shubh/baeldung/"

Here we assume that the current directory is where we want to clone the Git repo from. We then create a new folder called my_home_dir inside the current directory.

$ repo_path="tutorials/linux-bash/command-line-arguments/src/main/bash"

To obtain the absolute path of the script users-loop.sh, we first combine the values of two variables, my_home_dir (the directory where the repository resides) and repo_root (the root of the repository).

Let’s look at one possible solution −

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

As we can see here, the file_path holds the full path of the file user-loops.sh. Let’s now list (ls) the file user-loop.sh using this file_path −

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

As we can see above, our rewrite rule does exactly what we expect it to do. Note however, that the slash character (/) is not escaped within the regular expression itself. Therefore, if your server configuration allows such characters inside regular expressions, make sure to escape them properly. Otherwise, you may end up with unexpected results.

$ echo $my_home_dir
/home/shubh/baeldung/

$ repo_base_dir="${my_home_dir}///tutorials" && echo $repo_base_dir
/home/shubh/baeldung////tutorials

$ ls -ld $repo_base_dir/linux-bash
drwxr-xr-x 1 shubh shubh 512 May 3 18:07 /home/shubh/baeldung////tutorials/linux-bash

It works! Multiple \/ is not an issue in Unix paths. However, for better clarity, one may wish to remove the extra forward slashes in the path. We could utilize the realpath utility to accomplish this −

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

We use command substituion here to run the realpath command while displaying the directory contents.

A Generic Solution That Handles Special Cases

We discussed the technique for concatenating strings containing Linux paths in the previous sections. However, there may be some special cases, so let’s look at them now.

If someone passes an empty string or uses a relative path to concatentate with the first path, what would happen?

Here we go! Let’s see if our solution works for the special cases mentioned above.

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

We've created a Bash function called concatenate_path which takes two input paths as parameters.

Here, the first argument gets saved into the base_path varable and the second one into the sub_path variable; then, we use shell parametrization to deal with the case where the base path is empty.

${base_path:+$base_path/}

In the above condition if base_path is not set then nothing is substituted. Else the base_path is replaced with "base_path/". Hence we add the file separater to the base path only if the base_paht is set. Later we are dealing with the multiple slashes situation. Also the realpath command allows us to handle the multiple slashes situation while concatenateing the string.

Let's check our code by running some examples.

$ concatenate_paths "/home/shubh//" "baeldung//linux/"
/home/shubh/baeldung/linux

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

The results match our predictions. Now let’s see if we can give an empty string as the second argument −

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

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

It generated the correct path, and then we verified this by testing it using absolute paths. Now let's give relative paths instead.

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

Here we're showing the relative path (with the dot operator) compared to the first input, which works fine. Now let's make our example a bit more complicated and see if it still works −

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

It works seamlessly! So, we're able to verify all the cases discussed above.

Conclusion

We looked at different methods for building paths in Linux.

We first looked at a real world example of the problem. Then, we studied some basic techniques that could be used to solve the problem.

We then talked about some of the special cases which may arise when building a complete path.

We wrote a generic solution for handling the special case situations.

Updated on: 26-Dec-2022

449 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements