我正在寻找一种可能性,通过管道将多个多行字符串发送到 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]}"