有getStrings()
函数调用getPage()
函数返回一些html页面。该html通过egrep
和sed
组合传输,仅获得3个字符串。然后我尝试使用link
构造将每个字符串分别放入单独的变量profile
,gallery
,while read..
。但它只能在while...done
循环内部工作,因为它在子进程中运行。如何在getStrings()
函数之外使用这些变量?
getStrings() {
local i=2
local C=0
getPage $(getPageLink 1 $i) |
egrep *some expression that results in 3 strings* |
while read line; do
if (( (C % 3) == 0 )); then
link=$line
elif (( (C % 3) == 1 )); then
profile=$line
else
gallery=$line
fi
C=$((C+1)) #Counter
done
}
答案 0 :(得分:4)
简单:不要在子流程中运行循环:)
要实际完成,您可以使用流程替换。
while read line; do
...
done < <(getPage $(getPageLink 1 $i) | egrep ...)
对于好奇的,POSIX兼容的方法是使用命名管道(可能bash
使用命名管道来实现进程替换):
mkfifo pipe
getPage $(getPageLink 1 $i) | egrep ... > pipe &
while read line; do
...
done < pipe
从bash
4.2开始,您可以设置lastpipe
选项,这会导致管道中的最后一个命令在当前shell中运行,而不是子shell。
shopt -s lastpipe
getPage $(getPageLink 1 $i) | egrep ... | while read line; do
...
done
但是,使用while循环不是设置三个变量的最佳方法。在命令组中调用read
三次更容易,因此它们都从同一个流中读取。在上述三种情况中的任何一种情况下,用
{ read link; read profile; read gallery; }
如果您想要更灵活一点,请将您可能想要读取的变量的名称放在数组中:
fields=( link profile gallery )
然后用这个for循环替换while循环:
for var in "${fields[@]}"; do read $var; done
通过编辑fields
数组以获得适当的字段名称,这可以让您轻松调整代码,如果管道返回更多或更少的行。
答案 1 :(得分:0)
使用数组再解决一次:
getStrings() {
array_3=( `getPage | #some function
egrep | ...` ) #pipe conveyor
}