Execute command in a different directory
TL;DR
How do you execute a command/script in a different directory and stay where you were earlier?
(cd path/to/some/dir && ./some-script) |
Problem: Dance of cd
With Monorepo setup in many tech companies, we often run into situations where the command/script we want to run is not located (or not runnable) in the same directory where the terminal is (most likely the root directory of the repo).
Let’s say we have a monorepo project some-awesome-project
with both iOS and Android child directories:
├── android |
To build the Android project, we have to run ./gradlew build
in the android
directory because that’s where settings.gradle.kts
is located. If we run ./android/gradlew build
directly at the root directory of the repo, we will end up with an error complaining the root directory does not contain a Gradle build.
To avoid the build error, we have to do a dance of directory changing like this:
- Change directory:
cd android
- Run the command
./gradlew build
cd ..
back to where we were earlier because many other commands of our day-to-day workflow assume the terminal stays at the root directory of a repo
Solution: Subshell
To avoid the cd
dance back and forth, we can run the command in a subshell by enclosing the command inside parentheses:
(cd path/to/some/dir && ./some-script) |
Because the directory change made in a subshell does not carry over to the parent shell, it will stay in the same directory after the command in the subshell finishes.
Going back to our example, we can simply run (cd android && ./gradlew build)
directly at root directory:
$ pwd |