Velvet Star Monitor

Standout celebrity highlights with iconic style.

news

set global variable AND use stdout from bash function

Writer Andrew Mclaughlin

Here's the code:

#! /bin/bash
function foo() { G1=123 echo "ReturnVal"
}
RV="$(foo)"
echo "RV=$RV, G1=$G1" # RV=ReturnVal, G1=
foo >/dev/null
echo "G1=$G1" # G1=123

I want to execute the function, set global variable G1, AND capture the stdout of the function into a variable.

The first call fails to set the global variable because the function is executing in a subshell. But that's the canonical way to get stdout into a variable.

I realize the 2nd call to foo() is throwing away stdout. Writing it to the console is equally pointless for my purpose. But it illustrates that the function is capable of setting the global variable.

Note that any solution cannot use a temporary file on the filesystem. The function I'm actually trying to write is already dealing with temp files and their automatic cleanup; introducing another temp file is not an option.

Is there a way?

2 Answers

Are you coming from Java, C++? That doesn't look any BASH I've ever seen.

#!/bin/bash
myFunction()
{ echo eval " G1=\"123\"; echo \"My function \$G1\"; "
}
myVar=$(myFunction 2>&1);
source <(myFunction) 2>&1 >/dev/null;
echo "G1: $G1";
eval echo "myVar: $(grep -v eval <($myVar))"

Very messy because exporting variables from a subprocess to its parent isn't allowed.

G1: 123
myVar: My function 123
2

I ran into this problem myself recently, but in my case I couldn't separate my code into two separate functions, nor could I predict the name of the global variable I was going to set.

The following is what I came up with. The calling syntax is different, but easy enough. It may require some fiddling with backslash escapes, however.

Basically, it works like read, but while setting a global at the same time.

#!/usr/bin/env bash
function do_your_thing() { local name_of_capture_var="${1}" global_var="global global global global global" normally_sent_to_stdout="stdout stdout stdout stdout" eval "${name_of_capture_var}=\"${normally_sent_to_stdout}\""
}
function main() { local capture do_your_thing capture echo "In main():" echo "capture: ${capture}" echo "global_var: ${global_var}" echo
}
main
echo "Outside of main()"
echo "capture: ${capture}"
echo "global_var: ${global_var}"

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy