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.
If you are using oh my zsh, just activate the dotenv
plugin:
plugins+=(dotenv)
ZSH_DOTENV_FILE=.any-name-you-like-for-the-per-directory-alias-file
Also consider direnv, which lets you export environment variables in a per-directory .envrc
, and unset them when you move away (which dotenv
cannot do). direnv is compatible with all the popular shells. However, it doesn't currently let you define aliases or functions.
You can still combine ilkkachu's approach with direnv, by creating a function (rather than an alias) that decides what to do based on one (or several) environment variables, which are in turn set by direnv.
Both approaches deal with the security aspect by having you manually whitelist directories in which the dot files will be sourced.
Best Answer
It is not completely sure what you are asking, but an alias just expands to what is in the alias. If you have two aliases, you can append the different commands, even aliases.
In any other situation, you could specify a function in your
.bashrc
In case you have more choices, you could better use a case structure.