在子 shell 中进行替换以设置变量

在子 shell 中进行替换以设置变量

我正在尝试远程运行脚本并使用其标准输出来填充变量。我这样做是为了避免临时文件。

这是我正在尝试的模式:

var=$(bash <(curl -fsSkL http://remote/file.sh))
echo "var=${var}"

我正在测试这个模式而不curl使用cat

var=$(bash <(cat ./local/file.sh))
echo "var=${var}"

应该就语法而言是相同的。 ./local/file.shcontains echo hello,所以我希望var包含 value hello,但可惜的是,执行上述结果如下:

test.sh: command substitution: line 4: syntax error near unexpected token `('
test.sh: command substitution: line 4: `bash <(cat ./local/file.sh)'
var=

如何在不使用临时文件的情况下实现我的目标?

答案1

bash这些是当 shell 在 POSIX 模式下运行时尝试执行进程替换时出现的错误。 shellbash不支持 POSIX 模式下的进程替换。

bash将以 POSIX 模式运行,当

  1. set -o posix已被使用,或
  2. shell 被调用为sh.

我的预感是你有一个脚本,test.sh你正在运行它sh test.sh或者有一个#!/bin/shhashbang 行,并且你sh恰好是bash。另一种可能性是脚本确实不是#!根本有-line,并且它被bash-as-sh以某种其他方式调用。

相反,请确保您的test.sh脚本被 调用bash

例子:

$ cat script.sh
echo hello
$ cat test.sh
var=$(bash <( cat script.sh ))
printf 'var="%s"\n' "$var"
$ bash -o posix test.sh
test.sh: command substitution: line 2: syntax error near unexpected token `('
test.sh: command substitution: line 2: `bash <( cat script.sh ))'
var=""
$ bash test.sh
var="hello"

test.sh如果您想使用 POSIX在脚本中以可移植的方式执行此操作sh

var=$( cat script.sh | bash )
printf 'var="%s"\n' "$var"

这将影响进程bash读取其标准输入的输出cat,即不完全的与您的流程替换变体相同(仅保留标准输入)。如果内部 shell 执行的脚本以bash任何形式从其标准输入读取数据,这一点很重要。

如果您需要bash单独保留 shell 的标准输入(因为您需要从中读取),您可能会假设它mktemp可用并使用

var=$( tmpfile=$(mktemp); cat script.sh >"$tmpfile" && bash "$tmpfile"; rm -f "$tmpfile" )
printf 'var="%s"\n' "$var"

其中cat script.sh理解为稍后替换为您的curl命令。

如果您习惯于处理文件描述符,您还可以在调用 shell 之前将文件描述符 3 制作为标准输入描述符的副本bash,然后让获取的脚本从中读取:

var=$( exec 3<&0; cat script.sh | bash )
printf 'var="%s"\n' "$var"

然后该script.sh脚本将用于read -u 3读取原来的标准输入流,或utility <&3将该输入流重定向到另一个实用程序。

相关内容