4

How can I force a specific binary to be used when executing a bash script?

I have a bash script which uses the "php" binary.

There are several php versions on my computer. The main php binary, as configured via the PATH variable, is not the one to be used in this case.

Normally the script will be executed like this:

./script.sh

I need something like this:

php=/usr/bin/php ./script.sh

NOTE: It is not an option to temporary change the PATH variable just for this command, because this will affect other dependencies.

Hardcoding it in the script is also not an option, because the script is used by multiple people. So when other people execute the script it should just use the main php binary as specified in the PATH variable.

I don't want it to be accessible via a variable. I actually want to specify the exact location to look for the binary. Just like it would normally do by using PATH, only now for one single binary with the absolute path to it. If this script calls another script, that second script also needs to use that php version. –

6
  • Can you set the PHP path inside the script, and run it in there? (ie. PHP='/usr/bin/php' PHP script.php)
    – BriGuy
    Oct 18, 2013 at 14:16
  • What is php being used for? Can't you enforce a version in that script?
    – goldilocks
    Oct 18, 2013 at 14:18
  • Hardcoding it in the script is also not an option, because the script is used by multiple people. So when other people execute the script it should just use the main php binary as specified in the PATH variable. Oct 18, 2013 at 14:18
  • 1
    What's wrong with assigning the php variable before calling the script like you did?
    – Joseph R.
    Oct 18, 2013 at 16:21
  • @JosephR. I don't want it to be accessible via a variable. I actually want to specify the exact location to look for the binary. Just like it would normally do by using PATH, only now for one single binary with the absolute path to it. If this script calls another script, that second script also needs to use that php version. Oct 18, 2013 at 18:06

4 Answers 4

6

This would work:

php() {  /path/to/your/php $@; }; export -f php; ./script.sh ; unset -f php

To break it down:

php() {  /path/to/your/php $@; }; 

Defines a shell function that will pass all of its arguments to the php path you provide.

export -f php

Exports the newly created function for use within your script

./script.sh

Executes your script

unset -f php

Removes the shell function we defined earlier.

1
  • The above doesn't work for programs that look for php in $PATH, e.g. anything that isn't a Bourne-style shell. The right answer is to put the desired php in a directory that is first in $PATH - see my Oct 19 answer. Jan 24, 2014 at 22:46
3

One way to do it would be to add an additional variable to your script:

PHP=$1
if [ -z $PHP ]; then
    PHP=php
fi

Then, if you run it without specifing anything, it will use the default PHP binary. Else, it will use the one you'll pass through your variable

./script.sh /usr/bin/php
2
$ hash /usr/local/bin php
$ php file.php

help :

$ LANG=C help hash
hash: hash [-lr] [-p pathname] [-dt] [name ...]
    Remember or display program locations.

    Determine and remember the full pathname of each command NAME.  If
    no arguments are given, information about remembered commands is displayed.

    Options:
      -d                forget the remembered location of each NAME
      -l                display in a format that may be reused as input
      -p pathname       use PATHNAME is the full pathname of NAME
      -r                forget all remembered locations
      -t                print the remembered location of each NAME, preceding
                each location with the corresponding NAME if multiple
                NAMEs are given
    Arguments:
      NAME              Each NAME is searched for in $PATH and added to the list
                of remembered commands.

    Exit Status:
    Returns success unless NAME is not found or an invalid option is given.
10
  • 1
    Awesome, this is what I need. I modified the command a little bit to make it work "hash -p /usr/bin/php php". And afterwards optionally reset it with "hash -d php". Oct 19, 2013 at 11:49
  • @NickStemerdink Note that this has essentially the same effect as defining a function: the override is only effective when php is called by the same shell where you run hash`, not in subprocesses started from this script. Oct 20, 2013 at 1:12
  • @Gilles, You are right, I noticed that (even though I find this method more convenient). Is there a way to have subprocesses using the override? Oct 22, 2013 at 10:01
  • 1
    @Gilles, I know. But the problem is that the path to a folder should be specified, and not a absolute path to the binary. This causes other binaries in that directory to also have precedence. That's not what I want. I solved the problem now by creating a new directory for temporary overrides, and added that directory as the first one in $PATH (something like this answer: unix.stackexchange.com/a/96711/49486). Nov 6, 2013 at 16:25
  • 1
    Now, when I need a temporary override I create a symbolic link for that binary to the "override directory", then execute the main command, and then remove the symbolic link. Nov 6, 2013 at 16:34
1

You say NOTE: It is not an option to temporary change the PATH variable just for this command, because this will affect other dependencies, but I think it is an option if you do it right.

You can create a personal directory that has only your desired php in it, and put that personal directory first in your own PATH. That personal PATH entry will affect the shell finding only that one php binary, and not affect any other PATH dependencies. Other people running the script won't use your PATH, so it won't affect them. For example:

$ mkdir -p "$HOME/myphp"
$ ln -s /usr/bin/php "$HOME/myphp/"
$ PATH=$HOME/myphp:$PATH
$ ./script.sh

The above method only affects the one php program, nothing else, and it only affects it for you, not anyone else.

Of course you can put your new PATH definition in the shell start-up file for your account so that only the commands you run will use this version of php.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .