【问题标题】:In bash, how to `eval` a function definition?在 bash 中,如何评估函数定义?
【发布时间】:2021-06-30 23:20:45
【问题描述】:

我有如下函数定义:

function get-set-def() {
  flag=$1
  varname=$2

  case "${flag}" in
    -a)
      type ${varname} | sed -e 's|^|eval \$(alias |' -e $'s| is aliased to \`|=\'|' -e 's|$|)|'
      ;;

    -f)
      type ${varname} | tail -n +2 | sed -e $'1{ s/^/function /; }' -e $'${ s/$//; }'
      ;;

    -v)
      echo ${!varname} | sed -e "s|^|eval \$(${varname}=|" -e 's|$|)|'
      ;;
  esac
}

对于函数,在这种情况下,cdg 将输出:

$ get-set-def -f cdg
function cdg () 
{ 
    cd "$(git rev-parse --show-toplevel)"/"$1"
}

但如果我尝试 eval 它的输出,我会看到:

$(get-set-def -f cdg)
bash: function: command not found

即使复制和粘贴输出工作正常:

$ function cdg () 
{ 
    cd "$(git rev-parse --show-toplevel)"/"$1"
}
$ type cdg
cdg is a function
cdg () 
{ 
    cd "$(git rev-parse --show-toplevel)"/"$1"
}

我尝试了与eval 的不同组合(对于我尝试过的情况,它适用于aliases 和变量。需要做些什么才能使其适用于函数?

上下文:我知道将事物设置为已经存在的状态似乎很奇怪。我的计划是保存当前设置,以便以后重置。

【问题讨论】:

  • 试试eval "$(get-set-def -f cdg)"
  • @Abelisto,看起来可行,但我希望呼叫者不必这样做。
  • @Abelisto, type ${varname} | tail -n +2 | sed -e $'1{ s/^/eval \'function /; }' -e $'${ s/$/\'/; }' 看起来可行。我以为我已经尝试过了,但一定是某个地方有错字。如果您想发布该答案,我会投票。
  • 为什么不简单地declare -f cdg ??
  • get-set-def -f cdg 只是declare -f cdgsed -e $'1{ s/^/function /; }' -e $'${ s/$//; }' 你为什么要这样做?删除它。

标签: bash


【解决方案1】:

将各种 cmets 放在一起,echo "echo $(declare -f ${name}) | source" 有效。

同样echo "echo $(alias ${name}) | source" 用于-aecho "echo $(echo ${name}=${!name}) | source" 用于-v 工作。

总之,函数变为:

function get-set-def() {
  flag=$1
  name=$2
  
  local def
  case "${flag}" in
    -a)
      def="$(alias ${name})"
      ;;
    
    -f)
      def="$(declare -f ${name})"
      ;;
    
    -v)
      def="$(echo ${name}=${!name})"
      ;;
  esac

  echo "echo ${def} | source"
}

【讨论】:

    猜你喜欢
    • 2021-12-19
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    • 2014-01-01
    • 2015-03-30
    • 1970-01-01
    相关资源
    最近更新 更多