如何使用 bash 获取字符串中函数的内容?
How to get the content of a function in a string using bash?
我已经搜索过这个特定问题,但找不到任何有用的信息。
假设我在 ~/.bashrc
中定义了以下函数(注意:这是伪代码!):
ANDROID_PLATFORM_ROOT="/home/simao/xos/src/"
function getPlatformPath() {
echo "$ANDROID_PLATFORM_ROOT"
}
function addCaf() {
# Me doing stuff
echo "blah/$(getPlatformPath)"
}
function addAosp() {
# Me doing stuff
echo "aosp/$(getPlatformPath)"
}
function addXos() {
# Me doing stuff
echo "xos/$(getPlatformPath)"
}
function addAllAll() {
cd $(gettop)
# repo forall -c "addCaf; addAosp; addXos" # Does not work!
repo forall -c # Here is where I need all those commands
}
我的问题:
我需要在一行中获取函数 addCaf
、addAosp
和 addXos
。
你可以 运行 跟随 bash(伪代码):
dothis; dothat; doanotherthing; trythis && succeedsdothis || nosuccessdothis; blah
我想 运行 三个函数 addCaf
、addAosp
和 addXos
中的所有命令仅在一行中 .
感谢任何帮助。
我已经尝试过的:
repo forall -c "bash -c \"source ~/.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"
...这就是函数内部的代码行,你正在一个接一个地执行它们。
请注意,您还可以构建一个字符串变量,其中包含由 ; 分隔的所有代码行 if 而不是 运行 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"
注:
与原版不同的是不再干扰stdin
<(...)
替换是未转义的,因为它 必须 由原始 shell 执行,其中 foo
和 boo
首先被定义。它的输出将是一个 /dev/fd/63
形式的字符串,它是一个传递给第二个 shell 的文件描述符,其中包含转发的定义。
创建一个虚拟函数 foo(),它只打印 "bar":
foo() { echo bar ; }
现在有一个 bash
函数来打印 在 一个(或多个)函数中的内容。由于函数的内容缩进了 4 个空格,sed
删除了没有 4 个前导空格的任何行,然后也删除了前导空格,并添加了一个 ';'每个函数结束:
# Usage: in_func <function_name1> [ ...<function_name2> ... ]
in_func()
{ while [ "" ] ; do \
type | sed -n '/^ /{s/^ //p}' | sed '$s/.*/&;/' ; shift ; \
done ; }
打印 foo():
中的内容
in_func foo
输出:
echo bar;
将foo()中的内容分配给字符串$baz,然后打印$baz:
baz="`in_func foo`" ; echo $baz
输出:
echo bar;
运行 foo():
里有什么
eval "$baz"
输出:
bar
将 foo() 中的内容分配给 $baz 三次,然后 运行 it:
baz="`in_func foo foo foo`" ; eval "$baz"
输出:
bar
bar
bar
我已经搜索过这个特定问题,但找不到任何有用的信息。
假设我在 ~/.bashrc
中定义了以下函数(注意:这是伪代码!):
ANDROID_PLATFORM_ROOT="/home/simao/xos/src/"
function getPlatformPath() {
echo "$ANDROID_PLATFORM_ROOT"
}
function addCaf() {
# Me doing stuff
echo "blah/$(getPlatformPath)"
}
function addAosp() {
# Me doing stuff
echo "aosp/$(getPlatformPath)"
}
function addXos() {
# Me doing stuff
echo "xos/$(getPlatformPath)"
}
function addAllAll() {
cd $(gettop)
# repo forall -c "addCaf; addAosp; addXos" # Does not work!
repo forall -c # Here is where I need all those commands
}
我的问题:
我需要在一行中获取函数 addCaf
、addAosp
和 addXos
。
你可以 运行 跟随 bash(伪代码):
dothis; dothat; doanotherthing; trythis && succeedsdothis || nosuccessdothis; blah
我想 运行 三个函数 addCaf
、addAosp
和 addXos
中的所有命令仅在一行中 .
感谢任何帮助。
我已经尝试过的:
repo forall -c "bash -c \"source ~/.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"
...这就是函数内部的代码行,你正在一个接一个地执行它们。
请注意,您还可以构建一个字符串变量,其中包含由 ; 分隔的所有代码行 if 而不是 运行 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"
注:
与原版不同的是不再干扰stdin
<(...)
替换是未转义的,因为它 必须 由原始 shell 执行,其中foo
和boo
首先被定义。它的输出将是一个/dev/fd/63
形式的字符串,它是一个传递给第二个 shell 的文件描述符,其中包含转发的定义。
创建一个虚拟函数 foo(),它只打印 "bar":
foo() { echo bar ; }
现在有一个 bash
函数来打印 在 一个(或多个)函数中的内容。由于函数的内容缩进了 4 个空格,sed
删除了没有 4 个前导空格的任何行,然后也删除了前导空格,并添加了一个 ';'每个函数结束:
# Usage: in_func <function_name1> [ ...<function_name2> ... ]
in_func()
{ while [ "" ] ; do \
type | sed -n '/^ /{s/^ //p}' | sed '$s/.*/&;/' ; shift ; \
done ; }
打印 foo():
中的内容in_func foo
输出:
echo bar;
将foo()中的内容分配给字符串$baz,然后打印$baz:
baz="`in_func foo`" ; echo $baz
输出:
echo bar;
运行 foo():
里有什么eval "$baz"
输出:
bar
将 foo() 中的内容分配给 $baz 三次,然后 运行 it:
baz="`in_func foo foo foo`" ; eval "$baz"
输出:
bar
bar
bar