0

I am having issues getting cd to change directory given the output of a command.

For example, the following does not work:

# should be equivalent to "cd ~"
cd $(echo "~")
# should be equivalent to "cd ~/go"
cd $(echo "~/go")

Both returning an error such as

cd: no such file or directory: ~
cd: no such file or directory: ~/go

However, I am able to specify absolute paths, such as

cd $(echo "/Users/olly")

which will successfully change directory to that location. What's more, if I omit the quotes it will work.

cd $(echo ~)

At the moment, I have a program, jump-config, which will print the string of a path to the terminal.

jump-config
// prints ~/go/src/gitlab.com/ollybritton/jump/jump-config

I am attempting to do

cd $(jump-config)

but I am getting the error

cd: no such file or directory: ~/go/src/gitlab.com/ollybritton/jump/jump-config

I would be happy to do cd $JUMP_CONFIG, however, the program's output is not fixed and I need cd $(jump-config) to change.

I appreciate any explanation of the problem or help in advance.

Olly Britton
  • 115
  • 7

1 Answers1

1

Tilde expansion doesn't work in quotes, and should generally be avoided in scripting. It's intended for interactive use only. From man bash, / *Tilde Expansion:

If a word begins with an unquoted tilde character (`~'), all of the characters preceding the first unquoted slash (or all characters, if there is no unquoted slash) are considered a tilde-prefix. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible login name. If this login name is the null string, the tilde is replaced with the value of the shell parameter HOME. If HOME is unset, the home directory of the user executing the shell is substituted instead. Otherwise, the tilde-prefix is replaced with the home directory associated with the specified login name.

Would it be possible to modify jump-config to output $HOME in place of ~? If not, you could try one of these options:

jump_config=$(jump-config); cd "${jump_config//\~/$HOME}"

or

cd "$(jump-config |sed 's/~/$HOME/')"
vintnes
  • 1,874
  • 4
  • 16
  • Better to quote the output of the command substitution or directory names with spaces will fail badly. – Charles Duffy Apr 07 '19 at 22:32
  • BTW, the current answer works for `~/`, but not `~username/` or `~-/` or `~+/`, all of which have special meanings to the shell. One rather ugly but comprehensive approach is available in my answer to [How to manually expand a special variable (ex. tilde) in bash](https://stackoverflow.com/questions/3963716/how-to-manually-expand-a-special-variable-ex-tilde-in-bash/29310477#29310477) – Charles Duffy Apr 07 '19 at 22:33
  • @CharlesDuffy `foo=$(echo foo bar); echo $foo` – vintnes Apr 08 '19 at 01:03
  • I don't know what your comment is supposed to prove. `foo='foo bar'; echo $foo` passes *two separate* arguments to `echo` (which it then separates with spaces in its output), but `cd` expects *only one* argument, whether that argument contains literal spaces or not. – Charles Duffy Apr 08 '19 at 01:28
  • In order to solve the problem I ended up doing `eval cd $(jump-config)` This answer did put me on the right path, thanks. – Olly Britton Apr 08 '19 at 06:39