如何在环境变量中捕获bash命令组(花括号)的输出

问题描述 投票:0回答:2

例如,我可以使用子shell执行此操作:

VAL=$( do_something )

但是如何使用花括号实现相同的功能,以便命令不在子shell中执行?即这不起作用:

VAL={ do_something; }

TIA。

bash subshell
2个回答
0
投票

我不确定我理解你想要完成什么的原因,但是如果你能详细说明一点,我可以帮助你。

我确实推荐reading this fantastic write up关于实际发生了什么,以及为什么我不认为你想要在没有子shell的情况下调用进程。

但是,试着回答你的问题:

您无法在${}中运行命令,除非在未设置值的fallback子句中(在POSIX sh或bash中;在zsh中可能是可行的,这允许所有类型的古怪语法)。

但是,如果你真的想要这个,你可以这样调用cd

cdr() {
   if (( $# )); then
     command cd "$@"
   else
     local home
     home=$(git rev-parse --show-toplevel 2>/dev/null) || home=$HOME
     command cd "$home"
   fi
}

Note

  • 使用函数让我们测试我们的参数列表,使用分支逻辑,有局部变量,&c
  • 命令cd用于调用真正的cd实现而不是递归。

0
投票

set -e有点僵硬。尝试类似的东西

trap 'err=$?;
      echo >&2 "ERROR $err in $0 at line $LINENO, Aborting";
      exit $err;' ERR

在阅读日志时,这会提供更多信息,您可以在子shell中添加类似的命令。是的,这意味着将它添加到子shell中...但我经常在函数定义中执行此类操作,这些函数定义在子shell中调用。效果很好。

正在使用:

$ trap 'echo BOOM' ERR # parent shell trap for demo
$ false                # trigger manually for demo
BOOM
$ x="$( trap 'err=$?;
>             echo >&2 "ERROR $err in $0 at line $LINENO, Aborting";
>             exit $err;' ERR
>       date
>       pwd
>       false
>       echo "I shan't"
> )"
ERROR 1 in bash at line 7, Aborting
BOOM
$ echo "$x"
Thu, Jan 10, 2019  8:35:57 AM
/c/Users/P2759474/repos/Old/deploy_microservices
$

如果外壳有相同或类似的陷阱,它也会中止,另一条消息。 (使消息不同通常很有帮助。)


如果您不喜欢这样,那么作为一种笨拙的解决方法,您可以将数据删除到临时文件中。这是一个可以执行此操作的脚本。

set -ex
{ pwd
  date
  false
  echo "will this happen?"
} > foo
x=$(<foo)
echo "$x"

把它放在一个脚本中,它成功地保释了下来。

$: ./sete
+ pwd
+ date
+ false
$: echo $?
1

我仍然使用trap,但逻辑工作。 我也会使用mktemp和一个陷阱来删除退出时的临时等等......但是你明白了。

© www.soinside.com 2019 - 2024. All rights reserved.