1

realpath ~/test outputs /home/<user>/test.
Now, I have to use this in my bash script, so I have the path stored in a variable.
If I run the below commands in my shell it works.

export REMOTE_DIR=~/test
realpath $REMOTE_DIR

I have following script:

while true; do
    read -p "Enter the path of the Repository : " REMOTE_DIR
    if [ -d $(realpath $REMOTE_DIR) ]; then
            break;
    else
            echo "Path not found!! Please enter a valid path."
    fi
done

But I get the following error, realpath: '~/test': No such file or directory.

I observed that the same error occurs when I enclose path in quotes(double or single) as following:

export REMOTE_DIR='~/test'
realpath $REMOTE_DIR

I think the error has to do with something going wrong in the if statement condition. I guess the $REMOTE_DIR outputs '~/test' instead of ~/test.

What am I doing wrong?

EDIT :
Another issue in the same code: On inputting, ~/test, Path not found is output for the following code.

while true; do
    read -p "Enter the path of the Repository : " REMOTE_DIR
    if [ -d "$REMOTE_DIR" ]; then
            break;
    else
            echo "Path not found!! Please enter a valid path."
    fi
done

PS : I'm new to bash scripting!

  • 3
    `realpath ~/test outputs` `realpath` does not expand `~`, `~` is expanded _before_ `realpath` is executed. Do you want to run realpath __or__ do you want to expand `~`? Check your scripts with shellcheck. Why are you using realpath at all? Why do you export the variable? `If I run the below commands in my shell it works.` Yes, because `~` is expanded when assigning. Try `echo "$REMOTE_DIR"` first. Does https://stackoverflow.com/questions/3963716/how-to-manually-expand-a-special-variable-ex-tilde-in-bash answer your question? – KamilCuk Mar 19 '23 at 13:29
  • @KamilCuk, I have exported to check if `realpath` might work on the shell differently or something might be wrong in my script. I checked the above script with `shellcheck`, fixed all the errors (missing quotes) and still the same error. Here, in this example I want to expand `~` but in other scenarios such as `./` or `../../` I will be needing `realpath`. Tried `echo "$REMOTE_DIR"`, I get `~/test`, not the expanded path. If you are saying `~` is expanded when it is assigned, why am I getting this output as `~/test`? – Trevor Philip Mar 19 '23 at 13:53
  • 3
    Again, realpath does _not_ expand `~`. `ried echo "$REMOTE_DIR"` Try `REMOTE_DIR=~/test; echo "$REMOTE_DIR"`. Unquoted `~` is expanded _by shell upon use_, not by realpath. See the linked question. `If you are saying ~ is expanded when it is assigned` Because you used `REMOTE_DIR='~/test'`. Quotes are important. You have one version with and one without quotes. – KamilCuk Mar 19 '23 at 13:58
  • @KamilCuk, I guess using export was wrong. I understood that. So, basically expanding the `~` first using the solution in the linked question and then applying `realpath` might solve the issue here. Am I right? – Trevor Philip Mar 19 '23 at 14:11
  • Why realpath? There is no need for realpath. – KamilCuk Mar 19 '23 at 14:50
  • 2
    `realpath` is for resolving symbolic links, references to `..`, relative paths, etc. in a given path. It does not perform arbitrary directory-related shell expansions on a given string. – chepner Mar 19 '23 at 15:15
  • @KamilCuk `realpath` needed to convert relative path to absolute path in case of ../ ../../ – Trevor Philip Mar 20 '23 at 10:15
  • 1
    Why is it "needed"? If it's relative, `[ -d` will still detect it properly. Just use it. Does https://stackoverflow.com/questions/3963716/how-to-manually-expand-a-special-variable-ex-tilde-in-bash answer your question? It is a question about expanding `~` to user home directory. – KamilCuk Mar 20 '23 at 10:16
  • @KamilCuk, thanks for bearing with me. I finally understood about `realpath`. Didn't know that `-d` will detect relative path. And all my questions are answered. Thanks a lot! – Trevor Philip Mar 20 '23 at 10:40

1 Answers1

1

As part of a bash command, ~/ expands to the user's home directory. But read does not do this:

% read p                                                                
~/test
% echo $p                                                               
~/test

One solution would be to use a parameter to pass the REMOTE_DIR and let the shell invoking the script handle expansion:

#!/bin/bash
REMOTE_DIR="$1"
if [ ! -d "$REMOTE_DIR" ]; then
  echo "Not a directory: $REMOTE_DIR";
  exit 1;
fi
% ./t.sh ~/does-not-exist                                                 
Not a directory: /Users/user/does-not-exist

Using read to interactively prompt for user input is not common in the real world. Most programs will expect to be invoked with command line parameters.

erik258
  • 14,701
  • 2
  • 25
  • 31
  • Here is the scenario, I'm writing an automation script. And I need the source and target path input by the user when the script is run the first time, so I can write it off to a config file and I can then I source it every time I run the script. But, first I want to perform some basic checks such as, if the directory really exists when the user inputs a path. How do I achieve this? – Trevor Philip Mar 20 '23 at 10:08