bashcdsedfunctionxargs

Why does xargs cd throw an error when passed a name with a tilde?


I'm trying to create a function that goes to a specific directory, and if a single argument is specified add that to the directory string. But no matter what I try I can't get it to work and bash always reports that X is not a directory even though if I copy/paste it to a new command line it works from there.

function projects ()
{
  DIR=
  if [ -n "$1" ]
  then
    DIR=$1
  fi
  echo "~/Projects/Working Branches/$DIR" | sed 's/ /\\&/g' | xargs cd
}    

-

$ projects Parametric\ Search\ API
/usr/bin/cd: line 4: cd: ~/Projects/Working Branches/Parametric Search API: No such file or directory
$ projects "Parametric Search API"
/usr/bin/cd: line 4: cd: ~/Projects/Working Branches/Parametric Search API: No such file or directory

I've also tried modifying the sed regexp to s/ /\\\\\\&/g which produces what appears to be a properly escaped string, but results in the same exact error

$ projects Parametric\ Search\ API
/usr/bin/cd: line 4: cd: ~/Projects/Working\ Branches/Parametric\ Search\ API: No such file or directory
$ projects "Parametric Search API"
/usr/bin/cd: line 4: cd: ~/Projects/Working\ Branches/Parametric\ Search\ API: No such file or directory

An finally I've tried surrounding $DIR with every combination of quotes I can think of, but no luck so far.


Solution

  • So, one problem is that if you quote a path with ~ in it, the shell will not expand that before passing it into cd. You can fix this by using $HOME instead, or by putting the ~/ outside of the quotes.

    Also, you don't need to conditionally set $DIR based on $1, nor do you need to use sed and xargs. Just use $1 directly in your path; if it's empty, that directory component will be empty, leaving you with just the Working Branches directory as an argument to cd.

    Simply

    projects () {
      cd "$HOME/Projects/Working Branches/$1"
    }
    

    should work, as would the slightly shorter but less clear

    projects () {
      cd ~/"Projects/Working Branches/$1"
    }