繁体   English   中英

运行包含变量的别名时找不到命令

[英]Command not found when running alias containing variable

我想要 shell 别名有效地识别文件夹,以便在包含.php文件的文件夹中运行命令时,其内容仅为8.1 ,例如,运行相应的二进制文件。

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'

然而,上面的代码在运行phpv时返回了一个错误command not found php8.1 而单独运行php8.1 -v可以正常工作。

通常, alias用于缩短您经常键入的内容的简单文本。

alias ll=`ls -l`

如果您正在做比这更复杂的事情,请使用function ,而不是别名。

作为一个练习,让它接近你的原始想法 - 在你的 PATH 中设置你喜欢的默认值,但是当你想要一个结构来覆盖它时,而不是一个带有被破解/解析的数字的本地隐藏文件苍蝇,创建一个本地符号链接到该文件夹中所需的符号链接。 虽然这是一个安全问题,但您只需在路径中设置本地目录即可。 function 可以通过将更改本地化到特定 function 调用的 scope 来减轻安全问题。

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
}

当您开始需要需要一个版本或另一个版本的整个子目录结构时,这会下降,因为现在您必须将该符号链接(或 .php 文件或其他文件)放入该结构中的每个文件夹中,这是一团糟和维护噩梦.

更好的解决方案是设置尽可能干净的结构,并尝试将(仅)最高/最短的目录路径放在所有项目的顶部,并将需要备用版本的其他勘误表放入查找中。

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
}

这样,如果您运行phpv -v (或使用任何其他参数集),它应该使用最长匹配检查您在哪里获得覆盖的位置列表,这允许在子目录中进行不同的覆盖,但只需要覆盖到列出需要使用备用版本的最高、最短路径。 如果没有为您的当前目录或任何父目录找到覆盖,那么您默认为您的 PATH 中设置的任何内容。

使用我包含的示例路径,如果您在/usr/bin/etc//first/dir/to/delete或其他任何完全不符合其父系的地方,它将默认为您的路径。 如果您在/first/dir/to/edit/today ,它将匹配/first/dir/to/edit作为父级(该路径的任何子目录)并使用/opt/homebrew/Cellar/php@8.0/8.0.26/bin/php 如果您在/next/dir/for/lunch中,它将匹配/next/dir作为父级并使用/some/other/version/bin/php ,但在/next/dir/for/edits中,它匹配较长的路径首先使用/opt/homebrew/Cellar/php@8.0/8.0.26/bin/php代替。

希望所有这些都有助于激发一个有用的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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