4

Consider this:

$ cd /tmp
$ echo "echo YES" >> prog/myprog
$ chmod +x prog/myprog
$ prog/myprog
YES
$ myprog
myprog: command not found

I can temporarily modify PATH to call myprog by name like this:

$ PATH="$PATH":$(readlink -f prog) myprog
YES

... however I cannot chain commands with this approach:

$ PATH="$PATH":$(readlink -f prog) myprog && myprog
YES
myprog: command not found

... apparently the modified PATH apparently didn't propagate to the second invocation.

I'm aware I could do this:

$ PATH="$PATH":$(readlink -f prog) bash -c "myprog && myprog"
YES
YES

... but then I have to invoke an extra bash process - and even worse, I have to quote.

Is there any way to append to PATH temporarily for chained commands in a one-liner, without having to invoke extra bash and quote? Tried backticks, they don't work:

$ PATH="$PATH":$(readlink -f prog) `myprog && myprog`
myprog: command not found
  • 1
    Just in case, you still can call myprog by specifying the (relative in your case) path explicitly: prog/myprog. That saves you need to worry about PATH modifications. – Tagwint Mar 26 '16 at 16:22
6

How about using a subshell:

$ (PATH="$PATH:$(readlink -f prog)"; myprog && myprog)
YES
YES
  • Oh, that's quite neat, @cuonglm - thanks! – sdaau Mar 26 '16 at 16:02
  • 1
    please note that ( commands ) is conceptually equal to bash -c ' commands ' so you are activating extra bash process. (that I find usually acceptable) – Manwe Mar 26 '16 at 20:03
1

That will depend on what you consider "temporary". For example, you could just run:

$ PATH="$PATH":$(readlink -f prog) 

And then you would be able to run myprog to your heart's content for the rest of that shell session. The changes you made to PATH would disappear as soon as you logged out. You could just open a new terminal—if working graphically, or switch to a different tty, if not—or run a new session:

$ bash
$ PATH="$PATH":$(readlink -f prog) 
## Do your stuff here

$ exit

Another way of running the same thing is:

PATH="$PATH":$(readlink -f prog) bash

That will start a new bash session with the PATH variable changed. As soon as you're done, run exit to return to the parent.

  • Thanks for that @terdon - by temporary I meant for the duration of the (commands in the) one-liner only – sdaau Mar 26 '16 at 16:07
0

If you want that the path be changed only for the duration of the command.
Then, you need to set it for every time the command is called.
That's a perfect job for an alias:

alias myprog='PATH="$PATH":$(readlink -f prog) myprog'

Use as:

$ myprog && myprog
YES
YES

Of course, a function with the same name will not work:

$ myprog(){ PATH="$PATH":$(readlink -f prog) myprog; }  ### DO NOT USE !!

I am just wondering if you really need any of this. If you create the script inside ~/bin (after a login with the directory ~/bin created) the PATH variable will already include that path, and the script will be executed by just naming it:

$ cd ~/bin                   ### create the dir if it didn't exist.
$ echo "echo YES" >> myprog
$ chmod u+x myprog
$ cd ~
$ myprog                     ### remember to reload ~/.bashrc (re-login).
YES

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.