Shell script while read line loop stops after the first line





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







70















I have the following shell script. The purpose is to loop thru each line of the target file (whose path is the input parameter to the script) and do work against each line. Now, it seems only work with the very first line in the target file and stops after that line got processed. Is there anything wrong with my script?



#!/bin/bash
# SCRIPT: do.sh
# PURPOSE: loop thru the targets

FILENAME=$1
count=0

echo "proceed with $FILENAME"

while read LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh $LINE
done < $FILENAME

echo "ntotal $count targets"


In do_work.sh, I run a couple of ssh commands.










share|improve this question




















  • 1





    Your script is fine, but there might be something wrong with the do_work.sh

    – sleepsort
    Dec 10 '12 at 11:43






  • 2





    Yes, it could eat up all input, or it could be invoked as source and simply exit or exec. But this code doesn't look genuine, the OP would notice that echo requires -e to display line feed properly...

    – Michael Krelin - hacker
    Dec 10 '12 at 11:46








  • 2





    Does do_work.sh run ssh by any chance?

    – dogbane
    Dec 10 '12 at 11:48






  • 1





    yes, do_work.sh runs a couple ssh commands. anything special about that?

    – bcbishop
    Dec 10 '12 at 11:50






  • 1





    Better you show the do_work.sh source and also run do.sh with set -x to debug.

    – koola
    Dec 10 '12 at 11:56


















70















I have the following shell script. The purpose is to loop thru each line of the target file (whose path is the input parameter to the script) and do work against each line. Now, it seems only work with the very first line in the target file and stops after that line got processed. Is there anything wrong with my script?



#!/bin/bash
# SCRIPT: do.sh
# PURPOSE: loop thru the targets

FILENAME=$1
count=0

echo "proceed with $FILENAME"

while read LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh $LINE
done < $FILENAME

echo "ntotal $count targets"


In do_work.sh, I run a couple of ssh commands.










share|improve this question




















  • 1





    Your script is fine, but there might be something wrong with the do_work.sh

    – sleepsort
    Dec 10 '12 at 11:43






  • 2





    Yes, it could eat up all input, or it could be invoked as source and simply exit or exec. But this code doesn't look genuine, the OP would notice that echo requires -e to display line feed properly...

    – Michael Krelin - hacker
    Dec 10 '12 at 11:46








  • 2





    Does do_work.sh run ssh by any chance?

    – dogbane
    Dec 10 '12 at 11:48






  • 1





    yes, do_work.sh runs a couple ssh commands. anything special about that?

    – bcbishop
    Dec 10 '12 at 11:50






  • 1





    Better you show the do_work.sh source and also run do.sh with set -x to debug.

    – koola
    Dec 10 '12 at 11:56














70












70








70


15






I have the following shell script. The purpose is to loop thru each line of the target file (whose path is the input parameter to the script) and do work against each line. Now, it seems only work with the very first line in the target file and stops after that line got processed. Is there anything wrong with my script?



#!/bin/bash
# SCRIPT: do.sh
# PURPOSE: loop thru the targets

FILENAME=$1
count=0

echo "proceed with $FILENAME"

while read LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh $LINE
done < $FILENAME

echo "ntotal $count targets"


In do_work.sh, I run a couple of ssh commands.










share|improve this question
















I have the following shell script. The purpose is to loop thru each line of the target file (whose path is the input parameter to the script) and do work against each line. Now, it seems only work with the very first line in the target file and stops after that line got processed. Is there anything wrong with my script?



#!/bin/bash
# SCRIPT: do.sh
# PURPOSE: loop thru the targets

FILENAME=$1
count=0

echo "proceed with $FILENAME"

while read LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh $LINE
done < $FILENAME

echo "ntotal $count targets"


In do_work.sh, I run a couple of ssh commands.







bash shell ssh while-loop






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 3 '18 at 21:15









codeforester

18.8k84267




18.8k84267










asked Dec 10 '12 at 11:38









bcbishopbcbishop

60421021




60421021








  • 1





    Your script is fine, but there might be something wrong with the do_work.sh

    – sleepsort
    Dec 10 '12 at 11:43






  • 2





    Yes, it could eat up all input, or it could be invoked as source and simply exit or exec. But this code doesn't look genuine, the OP would notice that echo requires -e to display line feed properly...

    – Michael Krelin - hacker
    Dec 10 '12 at 11:46








  • 2





    Does do_work.sh run ssh by any chance?

    – dogbane
    Dec 10 '12 at 11:48






  • 1





    yes, do_work.sh runs a couple ssh commands. anything special about that?

    – bcbishop
    Dec 10 '12 at 11:50






  • 1





    Better you show the do_work.sh source and also run do.sh with set -x to debug.

    – koola
    Dec 10 '12 at 11:56














  • 1





    Your script is fine, but there might be something wrong with the do_work.sh

    – sleepsort
    Dec 10 '12 at 11:43






  • 2





    Yes, it could eat up all input, or it could be invoked as source and simply exit or exec. But this code doesn't look genuine, the OP would notice that echo requires -e to display line feed properly...

    – Michael Krelin - hacker
    Dec 10 '12 at 11:46








  • 2





    Does do_work.sh run ssh by any chance?

    – dogbane
    Dec 10 '12 at 11:48






  • 1





    yes, do_work.sh runs a couple ssh commands. anything special about that?

    – bcbishop
    Dec 10 '12 at 11:50






  • 1





    Better you show the do_work.sh source and also run do.sh with set -x to debug.

    – koola
    Dec 10 '12 at 11:56








1




1





Your script is fine, but there might be something wrong with the do_work.sh

– sleepsort
Dec 10 '12 at 11:43





Your script is fine, but there might be something wrong with the do_work.sh

– sleepsort
Dec 10 '12 at 11:43




2




2





Yes, it could eat up all input, or it could be invoked as source and simply exit or exec. But this code doesn't look genuine, the OP would notice that echo requires -e to display line feed properly...

– Michael Krelin - hacker
Dec 10 '12 at 11:46







Yes, it could eat up all input, or it could be invoked as source and simply exit or exec. But this code doesn't look genuine, the OP would notice that echo requires -e to display line feed properly...

– Michael Krelin - hacker
Dec 10 '12 at 11:46






2




2





Does do_work.sh run ssh by any chance?

– dogbane
Dec 10 '12 at 11:48





Does do_work.sh run ssh by any chance?

– dogbane
Dec 10 '12 at 11:48




1




1





yes, do_work.sh runs a couple ssh commands. anything special about that?

– bcbishop
Dec 10 '12 at 11:50





yes, do_work.sh runs a couple ssh commands. anything special about that?

– bcbishop
Dec 10 '12 at 11:50




1




1





Better you show the do_work.sh source and also run do.sh with set -x to debug.

– koola
Dec 10 '12 at 11:56





Better you show the do_work.sh source and also run do.sh with set -x to debug.

– koola
Dec 10 '12 at 11:56












3 Answers
3






active

oldest

votes


















136














The problem is that do_work.sh runs ssh commands and by default ssh reads from stdin which is your input file. As a result, you only see the first line processed, because ssh consumes the rest of the file and your while loop terminates.



To prevent this, pass the -n option to your ssh command to make it read from /dev/null instead of stdin.






share|improve this answer



















  • 22





    Or probably sh ./do_work.sh $LINE </dev/null

    – anishsane
    Dec 10 '12 at 12:23






  • 1





    yep, that'll do the trick as well.

    – bcbishop
    Dec 10 '12 at 12:32











  • Very useful, helped me to run this zsh oneliner: cat hosts | while read host ; do ssh $host do_something ; done

    – rat
    Jan 2 '18 at 16:43





















5














ssh -n option prevents checking the exit status of ssh when using HEREdoc while piping output to another program.
So use of /dev/null as stdin is preferred.



#!/bin/bash
while read ONELINE ; do
ssh ubuntu@host_xyz </dev/null <<EOF 2>&1 | filter_pgm
echo "Hi, $ONELINE. You come here often?"
process_response_pgm
EOF
if [ ${PIPESTATUS[0]} -ne 0 ] ; then
echo "aborting loop"
exit ${PIPESTATUS[0]}
fi
done << input_list.txt





share|improve this answer
























  • This doesn't make sense. The <<EOF overrides the </dev/null redirection. The << redirection after the done is wrong.

    – tripleee
    Mar 25 at 9:37



















0














More generally, a workaround which isn't specific to ssh is to redirect standard input for any command which might otherwise consume the while loop's input.



while read LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh "$LINE" </dev/null
done < "$FILENAME"


The addition of </dev/null is the crucial point here (though the corrected quoting is also somewhat important; see also When to wrap quotes around a shell variable?).



Another workaround of sorts which is somewhat specific to ssh is to make sure any ssh command has its standard input tied up, e.g. by changing



ssh otherhost some commands here


to instead read the commands from a here document, which conveniently (for this particular scenario) ties up the standard input of ssh for the commands:



ssh otherhost <<'____HERE'
some commands here
____HERE





share|improve this answer
























    protected by codeforester Aug 3 '18 at 21:14



    Thank you for your interest in this question.
    Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



    Would you like to answer one of these unanswered questions instead?














    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    136














    The problem is that do_work.sh runs ssh commands and by default ssh reads from stdin which is your input file. As a result, you only see the first line processed, because ssh consumes the rest of the file and your while loop terminates.



    To prevent this, pass the -n option to your ssh command to make it read from /dev/null instead of stdin.






    share|improve this answer



















    • 22





      Or probably sh ./do_work.sh $LINE </dev/null

      – anishsane
      Dec 10 '12 at 12:23






    • 1





      yep, that'll do the trick as well.

      – bcbishop
      Dec 10 '12 at 12:32











    • Very useful, helped me to run this zsh oneliner: cat hosts | while read host ; do ssh $host do_something ; done

      – rat
      Jan 2 '18 at 16:43


















    136














    The problem is that do_work.sh runs ssh commands and by default ssh reads from stdin which is your input file. As a result, you only see the first line processed, because ssh consumes the rest of the file and your while loop terminates.



    To prevent this, pass the -n option to your ssh command to make it read from /dev/null instead of stdin.






    share|improve this answer



















    • 22





      Or probably sh ./do_work.sh $LINE </dev/null

      – anishsane
      Dec 10 '12 at 12:23






    • 1





      yep, that'll do the trick as well.

      – bcbishop
      Dec 10 '12 at 12:32











    • Very useful, helped me to run this zsh oneliner: cat hosts | while read host ; do ssh $host do_something ; done

      – rat
      Jan 2 '18 at 16:43
















    136












    136








    136







    The problem is that do_work.sh runs ssh commands and by default ssh reads from stdin which is your input file. As a result, you only see the first line processed, because ssh consumes the rest of the file and your while loop terminates.



    To prevent this, pass the -n option to your ssh command to make it read from /dev/null instead of stdin.






    share|improve this answer













    The problem is that do_work.sh runs ssh commands and by default ssh reads from stdin which is your input file. As a result, you only see the first line processed, because ssh consumes the rest of the file and your while loop terminates.



    To prevent this, pass the -n option to your ssh command to make it read from /dev/null instead of stdin.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 10 '12 at 11:56









    dogbanedogbane

    194k66325375




    194k66325375








    • 22





      Or probably sh ./do_work.sh $LINE </dev/null

      – anishsane
      Dec 10 '12 at 12:23






    • 1





      yep, that'll do the trick as well.

      – bcbishop
      Dec 10 '12 at 12:32











    • Very useful, helped me to run this zsh oneliner: cat hosts | while read host ; do ssh $host do_something ; done

      – rat
      Jan 2 '18 at 16:43
















    • 22





      Or probably sh ./do_work.sh $LINE </dev/null

      – anishsane
      Dec 10 '12 at 12:23






    • 1





      yep, that'll do the trick as well.

      – bcbishop
      Dec 10 '12 at 12:32











    • Very useful, helped me to run this zsh oneliner: cat hosts | while read host ; do ssh $host do_something ; done

      – rat
      Jan 2 '18 at 16:43










    22




    22





    Or probably sh ./do_work.sh $LINE </dev/null

    – anishsane
    Dec 10 '12 at 12:23





    Or probably sh ./do_work.sh $LINE </dev/null

    – anishsane
    Dec 10 '12 at 12:23




    1




    1





    yep, that'll do the trick as well.

    – bcbishop
    Dec 10 '12 at 12:32





    yep, that'll do the trick as well.

    – bcbishop
    Dec 10 '12 at 12:32













    Very useful, helped me to run this zsh oneliner: cat hosts | while read host ; do ssh $host do_something ; done

    – rat
    Jan 2 '18 at 16:43







    Very useful, helped me to run this zsh oneliner: cat hosts | while read host ; do ssh $host do_something ; done

    – rat
    Jan 2 '18 at 16:43















    5














    ssh -n option prevents checking the exit status of ssh when using HEREdoc while piping output to another program.
    So use of /dev/null as stdin is preferred.



    #!/bin/bash
    while read ONELINE ; do
    ssh ubuntu@host_xyz </dev/null <<EOF 2>&1 | filter_pgm
    echo "Hi, $ONELINE. You come here often?"
    process_response_pgm
    EOF
    if [ ${PIPESTATUS[0]} -ne 0 ] ; then
    echo "aborting loop"
    exit ${PIPESTATUS[0]}
    fi
    done << input_list.txt





    share|improve this answer
























    • This doesn't make sense. The <<EOF overrides the </dev/null redirection. The << redirection after the done is wrong.

      – tripleee
      Mar 25 at 9:37
















    5














    ssh -n option prevents checking the exit status of ssh when using HEREdoc while piping output to another program.
    So use of /dev/null as stdin is preferred.



    #!/bin/bash
    while read ONELINE ; do
    ssh ubuntu@host_xyz </dev/null <<EOF 2>&1 | filter_pgm
    echo "Hi, $ONELINE. You come here often?"
    process_response_pgm
    EOF
    if [ ${PIPESTATUS[0]} -ne 0 ] ; then
    echo "aborting loop"
    exit ${PIPESTATUS[0]}
    fi
    done << input_list.txt





    share|improve this answer
























    • This doesn't make sense. The <<EOF overrides the </dev/null redirection. The << redirection after the done is wrong.

      – tripleee
      Mar 25 at 9:37














    5












    5








    5







    ssh -n option prevents checking the exit status of ssh when using HEREdoc while piping output to another program.
    So use of /dev/null as stdin is preferred.



    #!/bin/bash
    while read ONELINE ; do
    ssh ubuntu@host_xyz </dev/null <<EOF 2>&1 | filter_pgm
    echo "Hi, $ONELINE. You come here often?"
    process_response_pgm
    EOF
    if [ ${PIPESTATUS[0]} -ne 0 ] ; then
    echo "aborting loop"
    exit ${PIPESTATUS[0]}
    fi
    done << input_list.txt





    share|improve this answer













    ssh -n option prevents checking the exit status of ssh when using HEREdoc while piping output to another program.
    So use of /dev/null as stdin is preferred.



    #!/bin/bash
    while read ONELINE ; do
    ssh ubuntu@host_xyz </dev/null <<EOF 2>&1 | filter_pgm
    echo "Hi, $ONELINE. You come here often?"
    process_response_pgm
    EOF
    if [ ${PIPESTATUS[0]} -ne 0 ] ; then
    echo "aborting loop"
    exit ${PIPESTATUS[0]}
    fi
    done << input_list.txt






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 14 '15 at 22:54









    jacobm654321jacobm654321

    38438




    38438













    • This doesn't make sense. The <<EOF overrides the </dev/null redirection. The << redirection after the done is wrong.

      – tripleee
      Mar 25 at 9:37



















    • This doesn't make sense. The <<EOF overrides the </dev/null redirection. The << redirection after the done is wrong.

      – tripleee
      Mar 25 at 9:37

















    This doesn't make sense. The <<EOF overrides the </dev/null redirection. The << redirection after the done is wrong.

    – tripleee
    Mar 25 at 9:37





    This doesn't make sense. The <<EOF overrides the </dev/null redirection. The << redirection after the done is wrong.

    – tripleee
    Mar 25 at 9:37











    0














    More generally, a workaround which isn't specific to ssh is to redirect standard input for any command which might otherwise consume the while loop's input.



    while read LINE; do
    let count++
    echo "$count $LINE"
    sh ./do_work.sh "$LINE" </dev/null
    done < "$FILENAME"


    The addition of </dev/null is the crucial point here (though the corrected quoting is also somewhat important; see also When to wrap quotes around a shell variable?).



    Another workaround of sorts which is somewhat specific to ssh is to make sure any ssh command has its standard input tied up, e.g. by changing



    ssh otherhost some commands here


    to instead read the commands from a here document, which conveniently (for this particular scenario) ties up the standard input of ssh for the commands:



    ssh otherhost <<'____HERE'
    some commands here
    ____HERE





    share|improve this answer






























      0














      More generally, a workaround which isn't specific to ssh is to redirect standard input for any command which might otherwise consume the while loop's input.



      while read LINE; do
      let count++
      echo "$count $LINE"
      sh ./do_work.sh "$LINE" </dev/null
      done < "$FILENAME"


      The addition of </dev/null is the crucial point here (though the corrected quoting is also somewhat important; see also When to wrap quotes around a shell variable?).



      Another workaround of sorts which is somewhat specific to ssh is to make sure any ssh command has its standard input tied up, e.g. by changing



      ssh otherhost some commands here


      to instead read the commands from a here document, which conveniently (for this particular scenario) ties up the standard input of ssh for the commands:



      ssh otherhost <<'____HERE'
      some commands here
      ____HERE





      share|improve this answer




























        0












        0








        0







        More generally, a workaround which isn't specific to ssh is to redirect standard input for any command which might otherwise consume the while loop's input.



        while read LINE; do
        let count++
        echo "$count $LINE"
        sh ./do_work.sh "$LINE" </dev/null
        done < "$FILENAME"


        The addition of </dev/null is the crucial point here (though the corrected quoting is also somewhat important; see also When to wrap quotes around a shell variable?).



        Another workaround of sorts which is somewhat specific to ssh is to make sure any ssh command has its standard input tied up, e.g. by changing



        ssh otherhost some commands here


        to instead read the commands from a here document, which conveniently (for this particular scenario) ties up the standard input of ssh for the commands:



        ssh otherhost <<'____HERE'
        some commands here
        ____HERE





        share|improve this answer















        More generally, a workaround which isn't specific to ssh is to redirect standard input for any command which might otherwise consume the while loop's input.



        while read LINE; do
        let count++
        echo "$count $LINE"
        sh ./do_work.sh "$LINE" </dev/null
        done < "$FILENAME"


        The addition of </dev/null is the crucial point here (though the corrected quoting is also somewhat important; see also When to wrap quotes around a shell variable?).



        Another workaround of sorts which is somewhat specific to ssh is to make sure any ssh command has its standard input tied up, e.g. by changing



        ssh otherhost some commands here


        to instead read the commands from a here document, which conveniently (for this particular scenario) ties up the standard input of ssh for the commands:



        ssh otherhost <<'____HERE'
        some commands here
        ____HERE






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 25 at 9:39

























        answered Mar 25 at 9:32









        tripleeetripleee

        96.3k14134191




        96.3k14134191

















            protected by codeforester Aug 3 '18 at 21:14



            Thank you for your interest in this question.
            Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



            Would you like to answer one of these unanswered questions instead?



            Popular posts from this blog

            Monofisismo

            Angular Downloading a file using contenturl with Basic Authentication

            Olmecas