【问题标题】:Bash script - global variable becomes empty when function exitsBash脚本 - 函数退出时全局变量变为空
【发布时间】:2020-11-14 06:52:18
【问题描述】:

信息

我有一个问题,我想从 bash 脚本函数返回一个值(数组或字符串)。

我已经知道以下内容:

  • 名为 outputtext=$(functionName) 的 bash 脚本在子 shell 中运行
  • bash 函数的作用与“普通”编程语言不同,它只是返回 文本输出
  • bash 函数只能返回错误代码作为状态,并且可以通过$? 访问

测试脚本

我现在创建的一个测试脚本来演示我想要做什么,以及为什么我不能直接使用输出

   #!/bin/bash
   declare GLOBAL_VAR
   function callThis(){
      local output="==========================================\n"
      output="$output [START callThis()]\n"
      # For demonstration only - error 5 might be a built-in bash error code, but if caller
      # expects 0/5 they can be handled
      local statusCode=5
      # This variable is empty as soon as it exits the function
      GLOBAL_VAR="Some array value OR text output into GLOBAL_VAR"
      # Because the script has alot of text (echo'd/printf) output, and the function
      # calculates a result (array), I would like to have it as a RESULT
      # for another function.
      output="$output This is some output that will be sent to caller.\n"
      output="$output Test to see if GLOBAL_VAR is assigned:\n"
      output="$output '$GLOBAL_VAR'\n"
      output="$output [END callThis()]\n"
      output="$output ==========================================\n"
      echo -e $output
      return $((statusCode))
   }

   function startHere(){
      OUTPUT=$(callThis)
      STATUS_RESULT=$?
      echo -e "[Text output : $OUTPUT\n]"
      echo -e "[Status Code : $STATUS_RESULT\n]"
      echo -e "[Global VAR in startHere():\n'$GLOBAL_VAR']"
      if [ "$STATUS_RESULT" -eq 5 ]; then
         echo "Success! Status code $STATUS_RESULT found!"
      fi
   }

   echo -e $(startHere)
   echo "Global VAR is now (outside functions): '$GLOBAL_VAR'"

以上结果

我知道 echo -e 并没有给出这个函数的确切输出,除了这个主题

   [Text output :
   ========================================== 
   [START callThis()]
    This is some output that will be sent to caller. 
   Test to see if GLOBAL_VAR is assigned: 
   'Some array value OR text output into GLOBAL_VAR' 
   [END callThis()]
   ========================================== ] 
   [Status Code : 5 ] 
   [Global VAR in startHere(): '']
   Success! Status code 5 found!
   Global VAR is now (outside functions): ''

上面的脚本显示了我想做的大部分事情:我有很长的函数,有计算结果数组,并处理退出代码。

问题

由于它是在调用$(startHere) 时甚至在startHere() 中创建的子shell,所以GLOBAL_VAR 在callThis() 退出后立即为空。

我不知道如何继续,因为我需要另一个函数的值。我该如何解决这个问题?

解决方案

关于我提供的示例,请参阅 @mjrezaee 的解决方案。

原来我并不是所有事情都需要使用子shell$(),大部分时候直接调用函数,输出,全局变量,甚至错误码(返回码)都有. (我不经常使用 bash 脚本)。根据建议,我调整了我的 400 多行脚本,并且能够轻松使用全局变量。

【问题讨论】:

  • echo 将在函数中工作,而不是通过子外壳将其写入另一个变量。 $? 可以捕获结果代码,就像您在代码中使用的那样
  • 你已经有 1 小时要读的东西了,但无论如何stackoverflow.com/questions/7082001/…
  • 当问题得到回答时,您不必(或实际上不应该)更新问题 - 有一个公认的答案这一事实已经涵盖了这一点。
  • 如果我知道该怎么做,我会发布它作为答案,但我仍在学习;)我希望有类似 here-strings >>> 的东西用于将 fd 写入变量(在任何地方都没有找到)

标签: arrays bash shell command-line


【解决方案1】:

正如我在 cmets 中所说,您可以使用简单的函数调用,对测试代码的简单更改如下:

   #!/bin/bash
   declare GLOBAL_VAR
   function callThis(){
      local output="==========================================\n"
      output="$output [START callThis()]\n"
      # For demonstration only - error 5 might be a built-in bash error code, but if caller
      # expects 0/5 they can be handled
      local statusCode=5
      # This variable is empty as soon as it exits the function
      GLOBAL_VAR="Some array value OR text output into GLOBAL_VAR"
      # Because the script has alot of text (echo'd/printf) output, and the function
      # calculates a result (array), I would like to have it as a RESULT
      # for another function.
      output="$output This is some output that will be sent to caller.\n"
      output="$output Test to see if GLOBAL_VAR is assigned:\n"
      output="$output '$GLOBAL_VAR'\n"
      output="$output [END callThis()]\n"
      output="$output ==========================================\n"
      echo -e $output
      return $((statusCode))
   }

   function startHere(){
      # OUTPUT=$(callThis)
      callThis
      STATUS_RESULT=$?
      # echo -e "[Text output : $OUTPUT\n]"
      echo -e "[Status Code : $STATUS_RESULT\n]"
      echo -e "[Global VAR in startHere(): '$GLOBAL_VAR']"
      if [ "$STATUS_RESULT" -eq 5 ]; then
         echo "Success! Status code $STATUS_RESULT found!"
      fi
   }
   # echo -e $(startHere)
   startHere
   echo "Global VAR is now (outside functions): '$GLOBAL_VAR'"

输出:

==========================================
 [START callThis()]
 This is some output that will be sent to caller.
 Test to see if GLOBAL_VAR is assigned:
 'Some array value OR text output into GLOBAL_VAR'
 [END callThis()]
 ==========================================

[Status Code : 5
]
[Global VAR in startHere(): 'Some array value OR text output into GLOBAL_VAR']
Success! Status code 5 found!
Global VAR is now (outside functions): 'Some array value OR text output into GLOBAL_VAR'

this 也有助于解释其他使用 sub-shell 的方法

【讨论】:

  • 是的,谢谢,我从您的原始评论中发现了这一点。我现在正在尝试更新我的长脚本以使用这种调用函数的方法而不是 $() subshells。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 2016-03-03
相关资源
最近更新 更多