Print out variables from subshell to parent shell [duplicate]

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite













This question already has an answer here:



  • Why is my variable local in one 'while read' loop, but not in another seemingly similar loop?

    4 answers



Very new to Bash and pretty confused about local/global variables/subshells. I'm not sure why the modified variables won't print out at the end of the function—I'm trying to print out a final line count and file count at the end of the file, but if I do, it only prints out 0 because they are local variables. Is there any way to print out the modified values?



count=0
files=0
find . -type f | while IFC= read -r file;
do
let files=files+1
wc -l $file
count=$(($count+$(wc -l < $file)))
echo "total lines $count ; total files $files"
done
echo $files $count
exit 0






share|improve this question












marked as duplicate by Michael Homer, terdon♦ bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Nov 29 '17 at 18:36


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.














  • See mywiki.wooledge.org/BashFAQ/024
    – m0dular
    Nov 29 '17 at 23:48














up vote
1
down vote

favorite













This question already has an answer here:



  • Why is my variable local in one 'while read' loop, but not in another seemingly similar loop?

    4 answers



Very new to Bash and pretty confused about local/global variables/subshells. I'm not sure why the modified variables won't print out at the end of the function—I'm trying to print out a final line count and file count at the end of the file, but if I do, it only prints out 0 because they are local variables. Is there any way to print out the modified values?



count=0
files=0
find . -type f | while IFC= read -r file;
do
let files=files+1
wc -l $file
count=$(($count+$(wc -l < $file)))
echo "total lines $count ; total files $files"
done
echo $files $count
exit 0






share|improve this question












marked as duplicate by Michael Homer, terdon♦ bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Nov 29 '17 at 18:36


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.














  • See mywiki.wooledge.org/BashFAQ/024
    – m0dular
    Nov 29 '17 at 23:48












up vote
1
down vote

favorite









up vote
1
down vote

favorite












This question already has an answer here:



  • Why is my variable local in one 'while read' loop, but not in another seemingly similar loop?

    4 answers



Very new to Bash and pretty confused about local/global variables/subshells. I'm not sure why the modified variables won't print out at the end of the function—I'm trying to print out a final line count and file count at the end of the file, but if I do, it only prints out 0 because they are local variables. Is there any way to print out the modified values?



count=0
files=0
find . -type f | while IFC= read -r file;
do
let files=files+1
wc -l $file
count=$(($count+$(wc -l < $file)))
echo "total lines $count ; total files $files"
done
echo $files $count
exit 0






share|improve this question













This question already has an answer here:



  • Why is my variable local in one 'while read' loop, but not in another seemingly similar loop?

    4 answers



Very new to Bash and pretty confused about local/global variables/subshells. I'm not sure why the modified variables won't print out at the end of the function—I'm trying to print out a final line count and file count at the end of the file, but if I do, it only prints out 0 because they are local variables. Is there any way to print out the modified values?



count=0
files=0
find . -type f | while IFC= read -r file;
do
let files=files+1
wc -l $file
count=$(($count+$(wc -l < $file)))
echo "total lines $count ; total files $files"
done
echo $files $count
exit 0




This question already has an answer here:



  • Why is my variable local in one 'while read' loop, but not in another seemingly similar loop?

    4 answers









share|improve this question











share|improve this question




share|improve this question










asked Nov 29 '17 at 18:22









novel

83




83




marked as duplicate by Michael Homer, terdon♦ bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Nov 29 '17 at 18:36


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.






marked as duplicate by Michael Homer, terdon♦ bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Nov 29 '17 at 18:36


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.













  • See mywiki.wooledge.org/BashFAQ/024
    – m0dular
    Nov 29 '17 at 23:48
















  • See mywiki.wooledge.org/BashFAQ/024
    – m0dular
    Nov 29 '17 at 23:48















See mywiki.wooledge.org/BashFAQ/024
– m0dular
Nov 29 '17 at 23:48




See mywiki.wooledge.org/BashFAQ/024
– m0dular
Nov 29 '17 at 23:48










1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










Yes. But it is absolutely non-intuitive. This will work, for instance:



#!/bin/bash
count=0
files=0
while IFS= read -r file;
do
let files=files+1
wc -l $file
count=$(($count+$(wc -l < $file)))
echo "total lines $count ; total files $files"
done < <(find . -type f )
echo "$files $count"
exit 0


The <(command) construct is called "process substitution" and lets you treat the output of a command as a "file". Feeding it into the loop this way makes your script work as you expect.



The problem is your use of the pipe (|) which causes the while loop to run in a separate subshell which can't modify variables outside it.



In shells that don't support the <() feature, you can run the command(s) on the right of the pipe in a subsell and include the final echo in that subshell:



#!/bin/bash
files=0
find . -type f |
while IFC= read -r file;
do
let files=files+1
wc -l $file
count=$(($count+$(wc -l < $file)))
echo "total lines $count ; total files $files"
done
echo "$files $count"


exit 0





share|improve this answer





























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted










    Yes. But it is absolutely non-intuitive. This will work, for instance:



    #!/bin/bash
    count=0
    files=0
    while IFS= read -r file;
    do
    let files=files+1
    wc -l $file
    count=$(($count+$(wc -l < $file)))
    echo "total lines $count ; total files $files"
    done < <(find . -type f )
    echo "$files $count"
    exit 0


    The <(command) construct is called "process substitution" and lets you treat the output of a command as a "file". Feeding it into the loop this way makes your script work as you expect.



    The problem is your use of the pipe (|) which causes the while loop to run in a separate subshell which can't modify variables outside it.



    In shells that don't support the <() feature, you can run the command(s) on the right of the pipe in a subsell and include the final echo in that subshell:



    #!/bin/bash
    files=0
    find . -type f |
    while IFC= read -r file;
    do
    let files=files+1
    wc -l $file
    count=$(($count+$(wc -l < $file)))
    echo "total lines $count ; total files $files"
    done
    echo "$files $count"


    exit 0





    share|improve this answer


























      up vote
      1
      down vote



      accepted










      Yes. But it is absolutely non-intuitive. This will work, for instance:



      #!/bin/bash
      count=0
      files=0
      while IFS= read -r file;
      do
      let files=files+1
      wc -l $file
      count=$(($count+$(wc -l < $file)))
      echo "total lines $count ; total files $files"
      done < <(find . -type f )
      echo "$files $count"
      exit 0


      The <(command) construct is called "process substitution" and lets you treat the output of a command as a "file". Feeding it into the loop this way makes your script work as you expect.



      The problem is your use of the pipe (|) which causes the while loop to run in a separate subshell which can't modify variables outside it.



      In shells that don't support the <() feature, you can run the command(s) on the right of the pipe in a subsell and include the final echo in that subshell:



      #!/bin/bash
      files=0
      find . -type f |
      while IFC= read -r file;
      do
      let files=files+1
      wc -l $file
      count=$(($count+$(wc -l < $file)))
      echo "total lines $count ; total files $files"
      done
      echo "$files $count"


      exit 0





      share|improve this answer
























        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        Yes. But it is absolutely non-intuitive. This will work, for instance:



        #!/bin/bash
        count=0
        files=0
        while IFS= read -r file;
        do
        let files=files+1
        wc -l $file
        count=$(($count+$(wc -l < $file)))
        echo "total lines $count ; total files $files"
        done < <(find . -type f )
        echo "$files $count"
        exit 0


        The <(command) construct is called "process substitution" and lets you treat the output of a command as a "file". Feeding it into the loop this way makes your script work as you expect.



        The problem is your use of the pipe (|) which causes the while loop to run in a separate subshell which can't modify variables outside it.



        In shells that don't support the <() feature, you can run the command(s) on the right of the pipe in a subsell and include the final echo in that subshell:



        #!/bin/bash
        files=0
        find . -type f |
        while IFC= read -r file;
        do
        let files=files+1
        wc -l $file
        count=$(($count+$(wc -l < $file)))
        echo "total lines $count ; total files $files"
        done
        echo "$files $count"


        exit 0





        share|improve this answer














        Yes. But it is absolutely non-intuitive. This will work, for instance:



        #!/bin/bash
        count=0
        files=0
        while IFS= read -r file;
        do
        let files=files+1
        wc -l $file
        count=$(($count+$(wc -l < $file)))
        echo "total lines $count ; total files $files"
        done < <(find . -type f )
        echo "$files $count"
        exit 0


        The <(command) construct is called "process substitution" and lets you treat the output of a command as a "file". Feeding it into the loop this way makes your script work as you expect.



        The problem is your use of the pipe (|) which causes the while loop to run in a separate subshell which can't modify variables outside it.



        In shells that don't support the <() feature, you can run the command(s) on the right of the pipe in a subsell and include the final echo in that subshell:



        #!/bin/bash
        files=0
        find . -type f |
        while IFC= read -r file;
        do
        let files=files+1
        wc -l $file
        count=$(($count+$(wc -l < $file)))
        echo "total lines $count ; total files $files"
        done
        echo "$files $count"


        exit 0






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 18 '17 at 0:56









        Jeff Schaller

        32.1k849109




        32.1k849109










        answered Nov 29 '17 at 18:32









        terdon♦

        122k28230403




        122k28230403












            Popular posts from this blog

            Peggy Mitchell

            Palaiologos

            The Forum (Inglewood, California)