简体   繁体   中英

Command not found when running alias containing variable

I would like to have shell aliases that effectively are folder-aware, so that when running a command in a folder containing a .php file, the contents of which are just 8.1 for example, the corresponding binary is run.

alias php8.0='/opt/homebrew/Cellar/php@8.0/8.0.26/bin/php'
alias php8.1='/opt/homebrew/Cellar/php/8.1.13/bin/php'

alias phpv='php"$(cat .php)" -v'

The above however, when running phpv returns an error of command not found php8.1 . Whereas running php8.1 -v on its own works correctly.

Generally, alias is for simple text that shortens something you type often.

alias ll=`ls -l`

If you're doing anything more complicated that that, use a function , not an alias.

As an exercise, to keep it close to your otiginal idea - set whichever you prefer as the default in your PATH, but when you want a structure to override it, then instead of a local hidden file with a number that gets hack/parsed on the fly, create a local symlink to the one needed in that folder. While it's a security concern, you could just set the local directory in your path and be done. A function can lessen that security concern by localizing that change to the scope of the specific function call.

php() { [[ -L ./php ]] && local PATH=".:$PATH";         # only localize if local symlink exists
  local php=$(which php --skip-alias --skip-functions); # variable gets PATH-relevant version
  if [[ -x "$php" ]]                                    # checks for relevant success
  then "$php" "$@"                                      # runs appropriate version
  else "No PHP available."                              # reports if none
  fi
}

This falls down when you start needing entire subdirectory structures that need one version or the other, because now you have to put that symlink (or.php file, or whatever) in every folder in that structure, and it's a mess and a maintenance nightmare.

A better solution would be to set up as clean a structure as possible, and try to put (only) the highest/shortest directory paths at the top of all projects and miscellaneous errata that need alternate versions into a lookup.

phpv() { 
  local php='php'
  local -A altv=(
    [/first/dir/to/edit]="/opt/homebrew/Cellar/php@8.0/8.0.26/bin/php"
    [/next/dir]="/some/other/version/bin/php"
    [/next/dir/for/edits]="/opt/homebrew/Cellar/php@8.0/8.0.26/bin/php"
  )
  d="$PWD"                       # set longest path to check
  while [[ -n "$d" ]]
  do if [[ -n "${altv[$PWD]}" ]] # if there's an override
     then php="${altv[$PWD]}"    # override the varible
          break                  # get out, using the longest match
     fi
     d=${d%/*}                   # check one directory higher for an override
  done
  $php" "$@"                     # runs appropriate version
}

This way, if you run phpv -v (or with any other set of arguments) it should check where you are the list of places that get overrides, using the longest match, which allows different overrides in subdirectories, but only requires an override to list the highest, shortest paths that need to use an alternate version. If no overrides are found for your current directory or any parent, then you default to whatever is set in your PATH.

Using the example paths I included, if you are in /usr/bin or /etc/ or /first/dir/to/delete or anywhere else that exactly doesn't SOMEWHERE along its parentage, it will default to your PATH. If you are in /first/dir/to/edit/today it will match /first/dir/to/edit as a parent (any subdir of that path will) and use /opt/homebrew/Cellar/php@8.0/8.0.26/bin/php . If you are in /next/dir/for/lunch it will match /next/dir as a parent and use /some/other/version/bin/php , but in /next/dir/for/edits it matches the longer path first and uses /opt/homebrew/Cellar/php@8.0/8.0.26/bin/php instead.

Hope all that helps inspire a useful solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM