繁体   English   中英

没有子外壳的 Bash 字符串插值

[英]Bash string interpolation without subshell

我有这样的功能

print_stuff_and_set_vars() {
  IMPORTANT_VAL_1=""
  IMPORTANT_VAL_2=""
  echo -n "some stuff"
  echo -n "some more stuff"
  echo -n "result"
}

我这样称呼它:

my_main_func() {
  print_stuff_and_set_vars
  print_stuff_and_set_vars
  print_stuff_and_set_vars
  echo "IMPORTANT_VAL_1 was $IMPORTANT_VAL_1"
}

相反,我想将所有回显的结果保存到一个字符串中

my_main_func() {
  # doesn't work -- result is empty
  result="${print_stuff_and_set_vars}${print_stuff_and_set_vars}${print_stuff_and_set_vars}"
  echo "the result length was ${#result}"
  echo "$result"
  echo "IMPORTANT_VAL_1 was $IMPORTANT_VAL_1"
}

如果我使用$()而不是${}来启动子shell,这确实有效,但是没有设置全局变量。

有没有办法在不启动子shell的情况下将函数的结果保存到字符串中? 我知道在这个例子中显而易见的答案是将“结果”保存到全局变量而不是回显它,但在我的实际脚本中需要大量更改,如果可能的话我想避免它。

实际上,我只需要知道长度,所以如果有一种方法可以跟踪自函数启动以来打印了多少也可以正常工作。 如果这也zsh ,我实际上也在使用zsh

假设函数print_stuff_and_set_vars的输出不包含换行符,如何:

mkfifo p                        # create a named pipe "p"
exec 3<>p                       # open fd 3 for both reading and writing
rm p                            # now "p" can be closed

print_stuff_and_set_vars() {
  IMPORTANT_VAL_1="foo"
  IMPORTANT_VAL_2="bar"
  echo -n "some stuff "
  echo -n "some more stuff "
  echo -n "result "
}

my_main_func() {
  print_stuff_and_set_vars 1>&3 # redirect to fd 3
  print_stuff_and_set_vars 1>&3 # same as above
  print_stuff_and_set_vars 1>&3 # same as above
  echo 1>&3                     # send newline as an end of input

  IFS= read -r -u 3 result      # read a line from fd 3
  echo "the result length was ${#result}"
  echo "$result"
  echo "IMPORTANT_VAL_1 was $IMPORTANT_VAL_1"
}

my_main_func

exec 3>&-                       # close fd 3

输出:

the result length was 102
some stuff some more stuff result some stuff some more stuff result some stuff some more stuff result
IMPORTANT_VAL_1 was foo

使用临时文件很容易做到这一点。 例子:

print_stuff_and_set_vars() {
  IMPORTANT_VAL_1="x"
  IMPORTANT_VAL_2="y"
  echo -n "some stuff"
  echo -n "some more stuff"
  echo -n "result"
}

print_stuff_and_set_vars > /tmp/$$
myVar=$(< /tmp/$$)
echo $myVar 
echo $IMPORTANT_VAL_1
echo $IMPORTANT_VAL_2

也可以使用命名管道或文件描述符来实现这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM