【问题标题】:Loop control from within a subshell子外壳内的循环控制
【发布时间】:2014-02-21 06:32:49
【问题描述】:

我想使用子shell 来确保环境更改不会影响循环中的不同迭代,但我不确定是否可以在子shell 中使用循环控制语句(breakcontinue):

#!/bin/sh
export A=0
for i in 1 2 3; do
  (
  export A=$i
  if [ $i -eq 2 ]; then continue ; fi
  echo $i
  )
done
echo $A

循环外的A 的值不受循环内发生的任何事情的影响,这没关系。但是是否允许在子shell 内使用continue 还是应该将其移到外面?作为记录,它按其编写的方式工作,但也许这是一个不可靠的副作用。

【问题讨论】:

  • 这很有趣。由于子shell 是独立的进程(有自己的$BASHPID),因此您的代码会抛出通常的错误:continue: only meaningful in a 'for', 'while', or 'until' loop
  • 除非你真正的 subshel​​l 在现实中做更多的事情,否则 subshel​​l 中的 export 完全没有意义。

标签: bash dash-shell


【解决方案1】:

只需添加

echo "out $i"

在右括号之后看到它不起作用 - 它退出子shell,但继续循环。

以下是可行的:

#! /bin/bash
export A=0
for i in 1 2 3; do
    (
        export A=$i
        if [ $i -eq 2 ]; then exit 1 ; fi
        echo $i
    ) && echo $i out      # Only if the condition was not true.
done
echo $A

【讨论】:

  • 但这并没有解释为什么 bash 不抛出错误?试试这个,你会得到一个错误:(if [ 1 != 2 ]; then continue; fi)。为什么在循环中产生子shell时,OP不会发生同样的事情?
  • @grebneke 所以,如果我理解正确的话,循环包含的子shell 中的breakcontinue 只会导致子shell 退出,但不会影响循环。如果循环中的子shell后面没有任何内容(如我的示例),则效果相当于continue
  • @Jellby - 是的,它没有产生错误的原因是子shell是在周围的循环上下文中产生的。
【解决方案2】:

你能简单地将整个循环包装在一个子shell中吗?

#!/bin/sh
export A;
A=0
(
    for i in 1 2 3; do
        A=$i
        if [ $i -eq 2 ]; then continue ; fi
        echo $i
    done
)
echo $A

另请注意,您不需要在每次分配给变量时都使用exportexport 不导出值;它标记要导出的变量,以便在创建新进程时,该变量的当前值将添加到新进程的环境中。

【讨论】:

  • 不是在我的真实情况下,我还需要一次迭代而不影响下一次迭代。而且我事先不知道会导出哪些变量,这取决于特定于迭代的文件的内容。
猜你喜欢
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 2013-03-17
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 2014-06-27
相关资源
最近更新 更多