如何在循环时将输入传递给Bash并在循环结束后保留​​变量 [英] How to pipe input to a Bash while loop and preserve variables after loop ends

查看:100
本文介绍了如何在循环时将输入传递给Bash并在循环结束后保留​​变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Bash允许使用:cat <(echo "$FILECONTENT")

Bash allows to use: cat <(echo "$FILECONTENT")

Bash还允许使用:while read i; do echo $i; done </etc/passwd

Bash also allow to use: while read i; do echo $i; done </etc/passwd

可以结合使用前两个:echo $FILECONTENT | while read i; do echo $i; done

to combine previous two this can be used: echo $FILECONTENT | while read i; do echo $i; done

最后一个问题是它创建了子外壳,而在while循环结束后,变量i无法再访问.

The problem with last one is that it creates sub-shell and after the while loop ends variable i cannot be accessed any more.

我的问题是:

如何实现这样的目标:while read i; do echo $i; done <(echo "$FILECONTENT")或换句话说:如何确定i在while循环中仍然存在?

How to achieve something like this: while read i; do echo $i; done <(echo "$FILECONTENT") or in other words: How can I be sure that i survives while loop?

请注意,我知道将while语句包含在{}中,但这不能解决问题(假设您想在函数中使用while循环并返回i变量)

Please note that I am aware of enclosing while statement into {} but this does not solves the problem (imagine that you want use the while loop in function and return i variable)

推荐答案

流程替代是:

while read i; do echo $i; done < <(echo "$FILECONTENT")

循环终止时,在循环中分配的最后一个i值可用. 一种替代方法是:

The last value of i assigned in the loop is then available when the loop terminates. An alternative is:

echo $FILECONTENT | 
{
while read i; do echo $i; done
...do other things using $i here...
}

花括号是I/O分组操作,它们本身不会创建子外壳.在这种情况下,它们是管道的一部分,因此作为子外壳程序运行,但这是因为|而不是{ ... }.您在问题中提到了这一点. AFAIK,您可以从函数内部的这些函数中返回.

The braces are an I/O grouping operation and do not themselves create a subshell. In this context, they are part of a pipeline and are therefore run as a subshell, but it is because of the |, not the { ... }. You mention this in the question. AFAIK, you can do a return from within these inside a function.

Bash还提供了 shopt 内置,其众多选项之一是:

Bash also provides the shopt builtin and one of its many options is:

lastpipe

如果已设置并且作业控制未处于活动状态,则外壳程序将运行当前外壳程序环境中未在后台执行的管道的最后一条命令.

If set, and job control is not active, the shell runs the last command of a pipeline not executed in the background in the current shell environment.

因此,在脚本中使用类似这样的 可使修改后的sum在循环后可用:

Thus, using something like this in a script makes the modfied sum available after the loop:

FILECONTENT="12 Name
13 Number
14 Information"
shopt -s lastpipe   # Comment this out to see the alternative behaviour
sum=0
echo "$FILECONTENT" |
while read number name; do ((sum+=$number)); done
echo $sum

在命令行上执行此操作通常会导致作业控制未激活"(即在命令行上作业控制处于活动状态)的犯规.在不使用脚本的情况下进行测试失败.

Doing this at the command line usually runs foul of 'job control is not active' (that is, at the command line, job control is active). Testing this without using a script failed.

此外,如 Gareth Rees 在其此处为字符串:

Also, as noted by Gareth Rees in his answer, you can sometimes use a here string:

while read i; do echo $i; done <<< "$FILECONTENT"

这不需要shopt;您也许可以使用它来保存进程.

This doesn't require shopt; you may be able to save a process using it.

这篇关于如何在循环时将输入传递给Bash并在循环结束后保留​​变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆