为什么当我调用 bash -c 时源不起作用

为什么当我调用 bash -c 时源不起作用

我想运行一个命令来获取脚本来处理某些环境。执行之前的变量,而不是在我当前的 shell 中获取它们。

测试环境

export test=1

这些命令都没有回显环境。多变的:

a) 这不应该起作用吗?我不是只是在新的 shell 中执行这些命令并返回输出吗?

$ bash -c "source test.env && echo $test"

b) 这里我执行 test.env 并尝试使用 exec 在同一进程中运行 echo $test 。

$ bash -c "./test.env && exec echo $test"

c) 最后我只是尝试了这个,因为这是一个可能的排列。但它将 test.env 和 echo 命令作为单独的进程执行。

$ bash -c "./test.env && echo $test"

我怎样才能让它在环境中工作?变量是在执行第二个命令之前获取的吗?

答案1

您必须$在第一个命令中转义美元符号,否则bash将在命令执行之前展开它:

$ bash -c "source test.env && echo \$test"

或者您应该使用单引号而不是双引号:

$ bash -c 'source test.env && echo $test'

答案2

如果目标只是ENV在运行进程之前处理设置并避免影响当前 shell,那么exec执行bash可执行文件可能不是最有效的方法。

( . /dev/fd/4 && echo "$i" ) 4<<\SCRIPT
    i='i is set here in the subshell'
#END
SCRIPT

echo ${i?but i isnt set here because it was set in the subshell}

输出

i is set here in the subshell
sh: line 5: i: but i isnt set here because it was set in the subshell

您当然可以用常规文件替换heredoc文件描述符的链接 - 我只是用它来演示它。

但如果你 exec外部进程(例如bash或任何其他进程)而不是内置 shell,那么您不需要子 shell。

one=1 two=2 \
    bash -c 'echo "${cmd=This is command #}$one" 
             echo "${cmd}$two"'
echo "${one?this var was only set for the execed ENV}"

输出

This is command #1
This is command #2
sh: line 2: one: this var was only set for the execed ENV

如果那个外部进程 bash或任何其他符合-s默认接受 tdin 的 POSIX 标准的 shell,您可以直接将脚本写入文件|pipe...

{ echo PS1=
  echo 'echo "$PS1"'
  cat /etc/skel/.bashrc
  echo 'echo "$PS1"'
} | bash
echo "${PS1:?unset here again}"

输出

#blank line from first echo
[\u@\h \W]\$
sh: line 7: PS1: unset here again

答案3

正如所写的,shell$test在传递给您的命令之前正在扩展。您可以通过使用 a' 代替 来阻止这种情况发生"

bash -c 'source test.env && echo $test'

相关内容