0

bash 内置type可以很好地确定给定命令将做什么以及它是如何定义的,但是如果命令最终解析为文件,则不能直接提取文件路径。例如,要仅执行$PATH查找,您可以使用which

$ ls true
ls: cannot access true: No such file or directory
$ ls `which true`
/bin/true

假设我有一个别名:

alias notfalse=true

然后我不能只问which,但我可以问type

$ type notfalse
notfalse is aliased to `true'

但我想要的是让它通过调查来解决别名$PATH(不,各种标志type似乎不起作用)。

$ ls `somebuiltin notfalse`
/bin/true

忽略有一个true内置函数(我用别名隐藏),这只是一个例子。

4

3 回答 3

1

您可以解析输出alias notfalse然后使用type -P(正如 chepner 已经建议的那样)。

getaliaswithpath() {
   alias_str="$(alias "$1")"
   if [[ -n "$alias_str" ]]; then
      alias_str="${alias_str#*\'}"
      alias_str="${alias_str%%\'*}"
      type -P "$alias_str"
   else
      type -P "$1"
   fi
}

alias notfalse=true

getaliaswithpath notfalse

getaliaswithpath()(2013-09-13)的改进版本:

getaliaswithpath() {
   declare IFS alias_str exitflag substr
   exitflag=0
   alias_str="$(builtin alias "$1")"
   if [[ -n "$alias_str" ]]; then
      alias_str="${alias_str#*\'}"
      alias_str="${alias_str%%\'*}"

      # stop at first successful PATH lookup (before first | symbol)
      IFS=" "
      for substr in $alias_str; do
         [[ $exitflag -eq 1 ]] && return 1
         [[ "${substr:0:1}" == '-' ]] && continue   # skip cmd line options
         [[ "${substr//=/}" != "$substr" ]] && continue   # skip substr containing = symbol
         [[ "${substr}" == '|' ]] && { echo 'no cmd binary found' 1>&2; return 1; }  # stop at first | symbol
         [[ "${substr:0:1}" == '|' ]] && { echo 'no cmd binary found' 1>&2; return 1; }  # stop if substr begins with |

         if [[ "${substr: -1}" == '|' ]]; then   # if substr ends with | ...
            exitflag=1
            substr="${substr%?}"
         elif [[ "${substr//|/}" != "$substr" ]]; then   # if substr contains | symbol ...
            substr="${substr%%|*}"                       # ... extract first part up to first |
         fi

         #echo builtin type -P "$substr"

         builtin type -P "$substr" && return 0 
      done

   else
      builtin type -P "$1"
   fi
}


(

set -f   # disable globbing

# test cases
alias usort='LC_ALL=C sort -u | cat -n'
alias usort='LC_ALL=C sort -u| cat -n'
alias usort='LC_ALL=C sort -u |cat -n'
alias usort='LC_ALL=C sort -u|cat -n'
alias usort='LC_ALL=C sort|cat -n'

getaliaswithpath usort

)
于 2013-09-12T15:33:57.057 回答
1

type -P接近你想要的。从手册页:

-P 标志强制对每个 NAME 进行 PATH 搜索,即使它是别名、内置函数或函数,并返回将执行的磁盘文件的名称。

例如,我有ls别名为ls -G, 并type -P ls返回/bin/ls

但是,对于隐藏可执行文件的内置函数(如内置的trueshadows /bin/true),这将失败。我不确定有没有办法解决这个问题。对于 choroba 的示例,它也失败了csort

于 2013-09-12T14:03:11.233 回答
0

您可以尝试以下方法:

ls `alias | /usr/bin/which --read-alias notfalse | tail -1`

顺便说一句,我有自己的别名which,即:

alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
于 2013-09-12T12:31:54.850 回答