Bash – Alias to CD in a directory and call a command

aliasbashcd-command

I have a .bash_profile and in that I have a set of aliases. Those aliases at the moment execute only a single command and it was fairly easy. I would however like to do two things with a new alias that I'm trying to create.

  1. CD into a directory
  2. Run a command from that directory

Best Answer

To execute a command with a specific working directory, one usually does

( cd directory && utility )

The parentheses around the cd ... means that the command(s) therein runs in a subshell. Changing the working directory in a subshell makes it so that the current working directory of the calling shell is not changed, i.e., after having called this command, you would still be located in the same directory where you started.

Example:

( cd / && echo "$PWD" )  # will output "/"
echo "$PWD"              # will output whatever directory you were in at the start

This can not be turned into a generic alias as an alias can not take any arguments.

For a specific directory and utility, one could do

alias cdrun='( cd "$HOME/somedir" && ./script.sh )'

but for the general case, you would have to use a shell function:

cdrun () {
    ( cd "$1" && shift && command "$@" )
}

or

cdrun () (
    cd "$1" && shift && command "$@"
)

Replacing the curly braces with parentheses around the body of the function makes the function execute in its own subshell.

This would be used as

$ cdrun "$HOME/somedir" ./script.sh

which would run the script script.sh located in the directory $HOME/somedir, with $HOME/somedir as the working directory, or

$ cdrun / ls -l

which would provide you with a directory listing in "long format" of the root directory.

The shell function takes its first argument and tries to change to that directory. If that works, it shifts the directory name off from the positional parameters (the command line argument list) and executes the command given by the rest of the arguments. command is a built-in command in the shell which simply executes its arguments as a command.


All of this is needed if you want to execute a command with a changed working directory. If you just want to execute a command located elsewhere, you could obviously use

alias thing='$HOME/somedir/script.sh'

but this would run script.sh located in $HOME/somedir with the current directory as the working directory.

Another way of executing a script located elsewhere without changing the working directory is to add the location of the script to your PATH environment variable, e.g.

PATH="$PATH:$HOME/somedir"

Now script.sh in $HOME/somedir will be able to be run from anywhere by just using

$ script.sh

Again, this does not change the working directory for the command.

Related Question