What am I doing wrong in this bash function?
Question
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
function projects () {
cd "$HOME/Projects/Working Branches/$1"
}
should work, as would the slightly shorter but less clear
function projects () {
cd ~/"Projects/Working Branches/$1"
}
OTHER TIPS
The problem is that the tilde expansion is performed by the shell (bash) and that neither xargs nor cd nor the OS will do this. This is why the directory containing ~ is unknown. You could instead use $HOME instead of ~ whil will be replaced by the working directory between double quotes, or place the tilde outside the quotes (i.e., ~/"...").
Furthermore, calling cd with xargs will not change the working directory since cd is run in a separate process, consider just using cd ~/"Projects/Working Branches/" instead.
Maybe you're over-engineering this:
cd "~/Projects/Working Branches/"
cd "$DIR"
I don't really get the purpose of the sed
command, though, so maybe I'm missing something.
xargs
and cd
does not work together in my bash. I think it's because xargs
want an application and cd
is a built-in function in the bash shell.
try echo "Projects" | xargs cd
in your home directory to se if this is the case.
Another problem is that ~
doesn't get expanded as you think by echo. Try using the full path instead. Or use backticks to expand the ~
echo ´echo ~/`"Projects/Working Branches/$DIR"