3

I want to write a bash script that accepts, as an input argument, a file specification that includes one or more uses of the special characters ., .., and ~. I want my script's output to echo Bash's full path interpretation of my script.

Here is script I have tried:

a=$(ls -l -o -g "${1}" | cut --delimiter=' ' --fields=1-6 --complement -)

echo "\\"${a}\\""

If I issue command: myscript ~/.local/../.profile

The result returned is: /home/OldManK/.local/../.profile. But, I want: /home/OldManK/.profile.

Another example: myscript ~/./.profile returns: /home/OldManK/./.profile, but, I want: /home/OldManK/.profile.

Another (executed from /home/OldManK/.local): myscript ../.profile returns: ../.profile, but, I want: /home/OldManK/.profile.

Any alternate approaches, please?

5
  • Please "edit" your post and use code formatting for your code: that will greatly increase readability of your post and increase the chance someone reads it entirely through.
    – vanadium
    Oct 1, 2022 at 8:34
  • As a general rule, parsing ls is a very bad idea that should be avoided unless you have 100% control over the input file names, but even then it will break when using -l since the dates can change. See mywiki.wooledge.org/ParsingLs
    – terdon
    Oct 1, 2022 at 12:07
  • 3
    Note that it isn't actually bash responsible for parsing things like ../ -- this is done by the operating system kernel as part of handling open() and similar calls. Oct 1, 2022 at 16:24
  • 1
    Expansion of the ~ is done by the calling shell before it's passed to your script as an argument. That is, when you run myscript ~/.local/../.profile, the script actually receives "/home/OldManK/.local/../.profile" as its argument. If you want your script to handle ~ itself, things get more complicated (see this stackoverflow question). Oct 1, 2022 at 22:28
  • What you're looking for is sometimes called the "canonical" form of a path, with foo/../bar resolved (to bar if foo wasn't a symlink.) What's a "canonical path"? . The other part is shell-expansion of shell meta-characters like ~. Oct 2, 2022 at 7:13

1 Answer 1

11

Use realpath:

$ realpath ~/.local/bin/../mycommand
/home/user/.local/mycommand

From man realpath:

DESCRIPTION
    Print the resolved absolute file name; all but the last component must exist
2
  • Thanks, Jos. Perfect.
    – OldManK
    Oct 1, 2022 at 8:34
  • 2
    If my post was helpful, please check the mark next to it to mark the question as answered. Thanks.
    – Jos
    Oct 1, 2022 at 9:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .