Linux 如何使用bash获取字符串中函数的内容?

Linux 如何使用bash获取字符串中函数的内容?,linux,bash,shell,scripting,command,Linux,Bash,Shell,Scripting,Command,我已经搜索过这个特定的问题,但找不到任何有用的东西 假设在我的~/.bashrc中定义了以下函数(注意:这是伪代码!): 我的问题: 我需要在一行中获取函数addCaf、addAosp和addXos 您可以在bash中运行以下代码(伪代码): dothis;多特;什么都不做;这两件事都没有成功;废话 我想在一行中运行三个函数addCaf、addAosp和addXos中的所有命令 感谢您的帮助 我已经尝试过的: repo forall-c“bash-c\”源码~/.bashrc;addAllAll

我已经搜索过这个特定的问题,但找不到任何有用的东西

假设在我的
~/.bashrc
中定义了以下函数(注意:这是伪代码!):

我的问题:

我需要在一行中获取函数
addCaf
addAosp
addXos

您可以在bash中运行以下代码(伪代码):

dothis;多特;什么都不做;这两件事都没有成功;废话

我想在一行中运行三个函数
addCaf
addAosp
addXos
中的所有命令

感谢您的帮助

我已经尝试过的:

repo forall-c“bash-c\”源码~/.bashrc;addAllAll\“”

但这并不奏效

编辑:

澄清我的意思

因此,我想要这样的结果:

repo forall -c 'function getPlatformPath() { echo "$ANDROID_PLATFORM_ROOT"; }; ANDROID_PLATFORM_ROOT="/home/simao/xos/src/"; echo "blah/$(getPlatformPath)"; echo "aosp/$(getPlatformPath)"; echo "xos/$(getPlatformPath)"'
但我不想手动编写。相反,我想从已经存在的函数中获取这些行。

这应该可以:


repo forall-c“$(addCaf)$(addAosp)$(addXos)”

Shell函数对子进程不可见,除非导出它们。也许这就是缺少的成分

export -f addCaf addAosp addXos
repo forall -c "addCaf; addAosp; addXos"

您可以使用type,然后解析其输出,以便对代码行执行任何操作

$ foo() {
> echo foo
> }

$ type foo
foo is a function
foo () 
{ 
    echo foo
}
也许这个例子让事情变得更清楚了:

#!/bin/bash

foo() {
    echo "foo"
}

bar() {
    echo "bar"
}

export IFS=$'\n'

for f in foo bar; do
    for i in $(type $f | head -n-1 | tail -n+4); do
        eval $i
    done
done

exit 0
这就是它的样子:

$ ./funcs.sh 
foo
bar
脚本所做的是在所有函数上进行第一次循环(在本例中,只有foo和bar)。对于每个函数,它循环该函数的代码(跳过type的输出中无用的行)并执行它们。所以在最后,这和有这个代码是一样的

echo "foo"
echo "bar"
…这正是函数中的代码行,您正在一个接一个地执行它们

注意,您还可以构建一个字符串变量,其中包含由分隔的所有代码行如果不是在每行上运行eval,而是执行以下操作:

code_lines=

for f in foo bar; do
        for i in $(type $f | head -n-1 | tail -n+4); do
                if [ -z $code_lines ]; then
                        code_lines="$i"
                else
                        code_lines="${code_lines}; $i"
                fi  
        done
done

eval $code_lines

假设
repo forall-c
将下一个位置参数解释为
bash-c
,请尝试:

foo () { 
    echo "foo!"
}
boo () { 
    if true; then
        echo "boo!"
    fi
}
echo works | bash -c "source "<(typeset -f foo boo)"; foo; boo; cat"
foo(){
回声“福!”
}
boo(){
如果是真的,那么
回声“嘘!”
fi
}

echo works | bash-c“source”生成一个伪函数foo(),它只打印“bar”:

现在使用
bash
函数打印一个(或多个)函数中的内容。由于函数的内容缩进有4个空格,
sed
删除任何没有4个前导空格的行,然后也删除前导空格,并添加“;”在每个功能结束时:

# Usage: in_func <function_name1> [ ...<function_name2> ... ]
in_func() 
    { while [ "$1" ] ; do \
          type $1 | sed  -n '/^    /{s/^    //p}' | sed '$s/.*/&;/' ; shift ; \
      done ; }
输出:

echo bar;
echo bar;
bar
bar
bar
bar
foo()中的内容指定给字符串$baz,然后打印$baz:

输出:

echo bar;
echo bar;
bar
bar
bar
bar
运行foo()中的内容

in_func foo
eval "$baz"
输出:

echo bar;
echo bar;
bar
bar
bar
bar
foo()中的内容分配给$baz三次,然后运行它:

baz="`in_func foo foo foo`" ; eval "$baz"
输出:

echo bar;
echo bar;
bar
bar
bar
bar

不确定您要问什么,但是如果您想在一行上创建函数,可以使用
function f(){echo hi;}
。注意最后的
。好吧,我想在一行一个字符串中获取函数的内容。为什么您需要函数的内容而不只是运行函数本身?因为您需要将调用嵌入到
repo
(无论是什么)的参数中?
键入addXos
是否(大部分)完成了您需要的工作?或者实际上
declare-f addXos
?因为无论出于何种原因,
repo
工具都不接受这一点。我可以把这些东西写进引号里,但我很懒:从你的问题来看,
repo all-c
对下一个位置参数做了什么还不清楚。它是在其上运行shell替换(比如
bash-c
),还是将其解释为命令?最后两个代码片段提出了不同的建议。我不想要函数的结果,我想要内容。没问题,建议不错。尽管您的答案可能是正确的,但我仍面临以下错误消息:
出现错误,终止池:OSError:[Errno 2]没有这样的文件或目录
。似乎与
repo
工具有关。无论如何,在这种特殊情况下,这对我没有帮助。你知道我怎么能回显一个函数的内容,意思是所有单个命令吗?这几乎就是我需要的。您还可以告诉我如何删除
foo是一个函数
foo(){}
,只将行本身保留在一行中,如下所示:
echo foo;回声foo2;回声foo3,假设这些命令在特定的函数中?警告:有些人认为任何语言形式的
eval
都是eeville,。这是有效的。只需在函数中复制并粘贴
,然后运行以下命令:
repo forall-c“$(in_func addAosp)$(in_func addXos)$(in_func addCaf)
。但是
repo
工具有点问题。这个答案是正确的。删除间距并添加
-s对于较高的bash构造不起作用,例如
while
for
if
。例如:
boo(){while false;do echo bar;done;echo ok;};eval$(in_func boo)
给出了一个语法错误。(问题是_func
中的
do
之后添加了一个
)我在下面的某个地方给出的答案并不局限于此,但遗憾的是这被接受了。@MateiDavid,谢谢你的错误报告。我应该尝试
in_func in_func
,因为它也包含
。现在我在答案
sed
代码中添加了一个
do
检查。修改后的
do
更正--只需粘贴一个
仅在结尾处。应修复MateiDavid指出的问题。(如果不调用
sed
两次,则无法解决该问题。)