如何将 stdin 拆分为多个多行字符串并将每个字符串放入不同的 bash 变量中

如何将 stdin 拆分为多个多行字符串并将每个字符串放入不同的 bash 变量中

我正在寻找一种可能性,通过管道将多个多行字符串发送到 bash 脚本,并在该脚本中获取它们中的每一个。最后,我想将每个多行字符串存储到它自己的变量中。

printf "$some_multiline_string" "$another_multiline_string" | some_script.sh some_params

bash 内部:

#!/bin/bash
file1=$(</dev/stdin)
file2=$(</dev/stdin)
...

如何将 stdin 拆分为多个多行变量?

答案1

为什么不使用环境呢?

export some_multiline_string another_multiline_string

然后您可以从脚本内访问这些变量。

如果它们可能非常大并且超过了参数/envvar 的最大大小,或者它们组合起来超过了 arg+env 列表的最大大小,那么您可以使用管道传递它们:

myscript 3< <(printf %s "$some_multiline_string") \
         4< <(printf %s "$another_multiline_string") args

并在其中myscript

IFS= read -rd '' -u3 var1
IFS= read -rd '' -u4 var2
exec 3<&- 4<&-

或者您可以从单个流中传递它们,例如在脚本的 stdin 上传递它们,但用 NUL 分隔(这bash不能出现在变量中):

printf '%s\0' "$some_multiline_string" "$another_multiline_string" |
  myscript args

并在其中myscript

IFS= read -rd '' var1 && IFS= read -rd '' var2

答案2

我不完全确定我理解你的问题,但我认为你正在寻找的是:

script.sh "$some_multiline_string" "$another_multiline_string" param1 param2

然后,在脚本中,您将拥有:

file1="$1"
file2="$2"
param1="$3"
param2="$4"

如果你真的需要管道它,你可以这样做:

printf '%s\0%s' "$str1" "$str2" | script.sh param1 param2

并且,在脚本中:

#!/bin/bash
param1="$1"
param2="$2"

strings=()
while IFS= read -d '' str; do
    strings+=("$str")
done
printf 'String 1: %s\n\nString 2: %s\n' "${strings[0]}" "${strings[1]}"

例如:

$ str1="this is
a multiline
string"

$ str2="this is
another multiline
string"

$ printf '%s\0%s\0' "$str1" "$str2" | foo.sh
String 1: this is
a multiline
string

String 2: this is
another multiline
string

在 bash 4.4+ 版本中,您可以执行以下操作:

#!/bin/bash
param1="$1"
param2="$2"

strings=()
readarray -t -d '' strings

printf 'String 1: %s\n\nString 2: %s\n' "${strings[0]}" "${strings[1]}"

相关内容