1

I have a binary (emulator from the Android SDK Tools) that I use frequently. I've added it to my $PATH variable so that I can easily run the command with solely emulator.

However, it turns out that the binary uses relative paths; it complains if I run the script from a different directory. I'd really like to run the command from any folder without having to cd into the directory where the binary lives. Is there any way to get the script/bash into thinking I ran the command from the directory that it's located in?

thisissami
  • 15,445
  • 16
  • 47
  • 74

3 Answers3

2

A function is an appropriate tool for the job:

emu() ( cd /dir/with/emulator && exec ./emulator "$@" )

Let's break this down into pieces:

  • Using a function rather than an alias allows arguments to be substituted at an arbitrary location, rather than only at the end of the string an alias defines. That's critical, in this case, because we want the arguments to be evaluated inside a subshell, as described below:
  • Using parentheses, instead of curly brackets, causes this function's body to run in a subshell; that ensures that the cd only takes effect for that subshell, and doesn't impact the parent.
  • Using && to connect the cd and the following command ensures that we abort correctly if the cd fails.
  • Using exec tells the subshell to replace itself in memory with the emulator, rather than having an extra shell sitting around that does nothing but wait for the emulator to exit.
  • "$@" expands to the list of arguments passed to the function.
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
1

Add an alias (emu) to your ~/.bashrc:

alias emu="(cd /dir/with/emulator; ./emulator)"
Cyrus
  • 84,225
  • 14
  • 89
  • 153
  • @CharlesDuffy: Yes, both proposals are useful. Thank you. – Cyrus Mar 09 '17 at 21:26
  • @CharlesDuffy & Cyrus - having command-line arguments go through is crucial for this. CharlesDuffy - your solution works great. If either this answer is updated or a new answer is submitted, I'll accept it. – thisissami Mar 10 '17 at 00:32
0

I would look into command line aliases.

If you are in linux and using bash you can go to ~/.bash_profile and add a line such as:

alias emulator='./path-to-binary/emulator"

On windows it's a little different. Here is an example on how to do a similar thing in windows.

Community
  • 1
  • 1
bennerv
  • 86
  • 3
  • The alias proposed here doesn't change the working directory. – Charles Duffy Mar 09 '17 at 21:23
  • (...and part of the reason aliases are a questionable tool choice here is that it's tricky to make one that *does* change the working directory while scoping that change to only one command, and which also passes through command-line arguments, without also defining a function and just making the alias a wrapper for the function... at which point, why use an alias at all, rather than having a function do 100% of the work?) – Charles Duffy Mar 09 '17 at 21:38