0

This question already has an answer here:

This is my script. Even after using the export command not able to use variable outside of the block. Below is the code that i have tried. i have tried other option like declare -x var but that is also not working. Can someone please please comment on this, am i doing right?

#!/bin/bash
{
    var="123"  
    export var   # exporting the variable so that i can access from anywhere   
    echo "var is "$var     # able to get the value of this variable
} | tee   log.txt

echo "var is "$var   # not able to get the value of this variable

marked as duplicate by Michael Homer, PSkocik, Rui F Ribeiro, Stephen Rauch, Anthon Jul 2 '17 at 13:59

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • still solution is not clear for me , so what the changes i have to done in code to access that variable . and thanks for ur reply and for ur valuable time . – brajkishore dubey Jul 2 '17 at 8:47
  • The change you need to make is DON'T set the variable in a pipeline (except for the last segment in some non-bash shells and recent versions of bash with shopt lastpipe turned on, but you don't have it in the last segment anyway). – dave_thompson_085 Jul 2 '17 at 9:00
0

According to this accepted SOF answer:

In a pipeline, all commands run concurrently (with their stdout/stdin connected by pipes) so in different processes.

So although the curly braces by themselves do not create a subshell, the pipe then does this (in bash); see e.g.

#!/bin/bash
var=256

ps -u | grep $0
{
ps -u | grep $0
{
var="123"  
export var
echo "var is "$var

ps -u | grep $0

} | tee log.txt
echo "var is "$var
}

echo "var is "$var

So what we want is avoiding the pipe, while still having output on screen and to the logfile. Luckily bash got the feature <(...) for creating temporary FIFOs. Example below shows a possibility where one still can use a code block, transfer its whole output to a log (here stdout and stderr are appended to different log files) and have the changed variables accessible later, as we do not get into a subshell.

#!/bin/bash

VAR=123
echo "VAR first: $VAR"

{
        VAR=256
        echo "VAR in block: $VAR"
        norealcommand
        # show open files to see FIFOs
        #lsof -p $$
        date
        otherbadcommand
}> >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)

# dummy output to not mess up output order
echo | cat 

#lsof -p $$
echo "VAR after block: $VAR"

cat -n stdout.log 
cat -n stderr.log

which should result in something like this:

$ ./fifo                                                                            /dev/shm |myself@mydesk|0|12:04:10 
VAR first: 123
VAR in block: 256
./fifo: line 9: norealcommand: command not found
Mon Jul  3 12:04:37 CEST 2017
./fifo: line 13: otherbadcommand: command not found

VAR after block: 256
     1  VAR in block: 256
     2  Mon Jul  3 12:04:10 CEST 2017
     3  VAR in block: 256
     4  Mon Jul  3 12:04:37 CEST 2017
     1  ./fifo: line 9: norealcommand: command not found
     2  ./fifo: line 13: otherbadcommand: command not found
     3  ./fifo: line 9: norealcommand: command not found
     4  ./fifo: line 13: otherbadcommand: command not found

Hope this makes you happy :-)

  • awesome , thanks ! , thanks for ur valuable time , this solution is working . – brajkishore dubey Jul 2 '17 at 18:24
  • how to get the value of var="123" , outside of curly braces . I am getting output 123 , 256 ,256 .. but i want 123 123 123 . – brajkishore dubey Jul 2 '17 at 18:40
  • maybe you'd like to accept as answer if ithelped :-) – Jaleks Jul 5 '17 at 17:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.