Want to print output of two background shell functions sequentially

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











up vote
1
down vote

favorite












I have two functions in my shell scripts I run in background:



function foo 
# do a bunch of things
# print a lot of output


function bar
# do more things
# print out more things


foo &
bar &
wait


The output is printed out as it comes out to stdout or stderr, so there's a lot of overlap:



[foo] output line 1
[bar] output line 1
[foo] output line 2
[bar] output line 2


I'd like the output to be printed out sequentially (all of foo's output followed by all of bar's output) so that it's easier to read. Do I need to write the output to a file, then print out the file, or is there a way to do this without writing to files?










share|improve this question









New contributor




D Day is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 2




    Why do you run them in the background if you then wait for them? If you need their output sorted, is it crucial that they run simultaneously?
    – dessert
    3 hours ago










  • I'm doing this in order to save time. Each function takes about a minute to run, but they don't depend on each other.
    – D Day
    3 hours ago










  • @DDay They may not depend on each other, but in your description their outputs do depend on each other sequentially. So instead of hacky tricks, just do everything without backgrounding. Or make one function call the other.
    – Sergiy Kolodyazhnyy
    2 hours ago














up vote
1
down vote

favorite












I have two functions in my shell scripts I run in background:



function foo 
# do a bunch of things
# print a lot of output


function bar
# do more things
# print out more things


foo &
bar &
wait


The output is printed out as it comes out to stdout or stderr, so there's a lot of overlap:



[foo] output line 1
[bar] output line 1
[foo] output line 2
[bar] output line 2


I'd like the output to be printed out sequentially (all of foo's output followed by all of bar's output) so that it's easier to read. Do I need to write the output to a file, then print out the file, or is there a way to do this without writing to files?










share|improve this question









New contributor




D Day is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 2




    Why do you run them in the background if you then wait for them? If you need their output sorted, is it crucial that they run simultaneously?
    – dessert
    3 hours ago










  • I'm doing this in order to save time. Each function takes about a minute to run, but they don't depend on each other.
    – D Day
    3 hours ago










  • @DDay They may not depend on each other, but in your description their outputs do depend on each other sequentially. So instead of hacky tricks, just do everything without backgrounding. Or make one function call the other.
    – Sergiy Kolodyazhnyy
    2 hours ago












up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have two functions in my shell scripts I run in background:



function foo 
# do a bunch of things
# print a lot of output


function bar
# do more things
# print out more things


foo &
bar &
wait


The output is printed out as it comes out to stdout or stderr, so there's a lot of overlap:



[foo] output line 1
[bar] output line 1
[foo] output line 2
[bar] output line 2


I'd like the output to be printed out sequentially (all of foo's output followed by all of bar's output) so that it's easier to read. Do I need to write the output to a file, then print out the file, or is there a way to do this without writing to files?










share|improve this question









New contributor




D Day is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I have two functions in my shell scripts I run in background:



function foo 
# do a bunch of things
# print a lot of output


function bar
# do more things
# print out more things


foo &
bar &
wait


The output is printed out as it comes out to stdout or stderr, so there's a lot of overlap:



[foo] output line 1
[bar] output line 1
[foo] output line 2
[bar] output line 2


I'd like the output to be printed out sequentially (all of foo's output followed by all of bar's output) so that it's easier to read. Do I need to write the output to a file, then print out the file, or is there a way to do this without writing to files?







command-line bash scripts printing






share|improve this question









New contributor




D Day is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




D Day is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 3 hours ago









K7AAY

3,84221543




3,84221543






New contributor




D Day is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 4 hours ago









D Day

62




62




New contributor




D Day is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





D Day is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






D Day is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







  • 2




    Why do you run them in the background if you then wait for them? If you need their output sorted, is it crucial that they run simultaneously?
    – dessert
    3 hours ago










  • I'm doing this in order to save time. Each function takes about a minute to run, but they don't depend on each other.
    – D Day
    3 hours ago










  • @DDay They may not depend on each other, but in your description their outputs do depend on each other sequentially. So instead of hacky tricks, just do everything without backgrounding. Or make one function call the other.
    – Sergiy Kolodyazhnyy
    2 hours ago












  • 2




    Why do you run them in the background if you then wait for them? If you need their output sorted, is it crucial that they run simultaneously?
    – dessert
    3 hours ago










  • I'm doing this in order to save time. Each function takes about a minute to run, but they don't depend on each other.
    – D Day
    3 hours ago










  • @DDay They may not depend on each other, but in your description their outputs do depend on each other sequentially. So instead of hacky tricks, just do everything without backgrounding. Or make one function call the other.
    – Sergiy Kolodyazhnyy
    2 hours ago







2




2




Why do you run them in the background if you then wait for them? If you need their output sorted, is it crucial that they run simultaneously?
– dessert
3 hours ago




Why do you run them in the background if you then wait for them? If you need their output sorted, is it crucial that they run simultaneously?
– dessert
3 hours ago












I'm doing this in order to save time. Each function takes about a minute to run, but they don't depend on each other.
– D Day
3 hours ago




I'm doing this in order to save time. Each function takes about a minute to run, but they don't depend on each other.
– D Day
3 hours ago












@DDay They may not depend on each other, but in your description their outputs do depend on each other sequentially. So instead of hacky tricks, just do everything without backgrounding. Or make one function call the other.
– Sergiy Kolodyazhnyy
2 hours ago




@DDay They may not depend on each other, but in your description their outputs do depend on each other sequentially. So instead of hacky tricks, just do everything without backgrounding. Or make one function call the other.
– Sergiy Kolodyazhnyy
2 hours ago










3 Answers
3






active

oldest

votes

















up vote
3
down vote













Every output is written to a file anyway, I don’t know of a way not to use files. I’d use tempfiles as needed, e.g.:



$ a=$(mktemp)
$ b=$(mktemp)
$ echo 1 >$a & echo 2 >$b & wait
$ cat $b
2
$ cat $a
1


mktemp creates two tempfiles a and b, the echo commands write to the tempfiles, you can then use cat to print from them at any time you need the output. If you want to redirect both stdout and stderr, use &> instead.






share|improve this answer






















  • Clever. Reading file descriptors in sequence you want. +1
    – Sergiy Kolodyazhnyy
    2 hours ago










  • @PerlDuck correct, I mixed up two things there
    – dessert
    1 hour ago










  • @SergiyKolodyazhnyy I didn’t manage to use fd’s here, do you know a way? However, it’s not much of a difference to tempfiles created by mktemp…
    – dessert
    1 hour ago











  • This unix.stackexchange.com/a/122101/251553 looks scary but might be adapted to the problem at hand. ;-) I haven't tried, though.
    – PerlDuck
    1 hour ago







  • 2




    @perlduck The $(...) is implemented with anonymous temp files as well, so not much difference to what dessert is doing which is much more explicit and clear, IMHO.
    – Sergiy Kolodyazhnyy
    1 hour ago

















up vote
1
down vote













I would like to see a complete solution, that will be efficient on large number of records. Meanwhile if you have few hundred lines or lot of time (for few hundred thousands lines) you can try something like this:





#!/bin/bash

# Two functions that do number of things
foo() for i in 1..3; do echo "foo $i."; done; exit 0;
bar() for i in 1..5; do echo "bar .$i"; done; exit 0;

# The missing function :)
log_cat() wc -l)" && echo "[bar lines]: $BAR_LINES"

# Get the bigger lines number
if (( FOO_LINES >= BAR_LINES )); then LINES="$FOO_LINES"; else LINES="$BAR_LINES"; fi

for (( LINE=1; LINE<=LINES; LINE++ ))
do
# Use `sed' to `p'rint only the current $LINE from both log files;
# `-n' will suppress the rest output of `sed':
# sed -n "$LINE p" "$FOO_LOG" && sed -n "$LINE p" "$BAR_LOG"
# Use the above with `printf' for better formatting
printf 'n[foo %sn[bar %sn' "$LINE]: $(sed -n "$LINE p" "$FOO_LOG")" "$LINE]: $(sed -n "$LINE p" "$BAR_LOG")"
done


# Define log files
FOO_LOG="/tmp/prefix_foo.tmp"
BAR_LOG="/tmp/prefix_bar.tmp"

# Execute the two functions and redirect their stdout to the log files
foo > "$FOO_LOG" &
bar > "$BAR_LOG" &
wait

# Concatenate the log files in the desired way
log_cat


Sample output:



$ ./rotate.sh 
[foo lines]: 3
[bar lines]: 5

[foo 1]: foo 1.
[bar 1]: bar .1

[foo 2]: foo 2.
[bar 2]: bar .2

[foo 3]: foo 3.
[bar 3]: bar .3

[foo 4]:
[bar 4]: bar .4

[foo 5]:
[bar 5]: bar .5





share|improve this answer






















  • @dessert, done. Thanks!
    – pa4080
    24 mins ago










  • Oh, I thought you were printing in columns, misread the printf – I think OP wanted to separate the two outputs: “all of foo's output followed by all of bar's output”
    – dessert
    16 mins ago

















up vote
0
down vote













Well, the system is writing to files anyway to accomplish this; they're just temp files. However, you could have the foo process output to one file and rename it when complete. Have bar watch for the rename of said file, and when foo completes the rename, bar outputs the foo output then prints its own output, a la:



function foo 
# do a bunch of things
# print a lot of output to /tmp/foo.work
# mv /tmp/foo.work /tmp/foo.done


function bar
# do more things
# write more things to /tmp/bar.done
# if exist /tmp/foo.done print /tmp/foo.done else wait 1 and recheck
# rm /tmp/foo.done
# print /tmp/bar.done






share|improve this answer






















    Your Answer








    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "89"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );






    D Day is a new contributor. Be nice, and check out our Code of Conduct.









     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1089250%2fwant-to-print-output-of-two-background-shell-functions-sequentially%23new-answer', 'question_page');

    );

    Post as a guest






























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    3
    down vote













    Every output is written to a file anyway, I don’t know of a way not to use files. I’d use tempfiles as needed, e.g.:



    $ a=$(mktemp)
    $ b=$(mktemp)
    $ echo 1 >$a & echo 2 >$b & wait
    $ cat $b
    2
    $ cat $a
    1


    mktemp creates two tempfiles a and b, the echo commands write to the tempfiles, you can then use cat to print from them at any time you need the output. If you want to redirect both stdout and stderr, use &> instead.






    share|improve this answer






















    • Clever. Reading file descriptors in sequence you want. +1
      – Sergiy Kolodyazhnyy
      2 hours ago










    • @PerlDuck correct, I mixed up two things there
      – dessert
      1 hour ago










    • @SergiyKolodyazhnyy I didn’t manage to use fd’s here, do you know a way? However, it’s not much of a difference to tempfiles created by mktemp…
      – dessert
      1 hour ago











    • This unix.stackexchange.com/a/122101/251553 looks scary but might be adapted to the problem at hand. ;-) I haven't tried, though.
      – PerlDuck
      1 hour ago







    • 2




      @perlduck The $(...) is implemented with anonymous temp files as well, so not much difference to what dessert is doing which is much more explicit and clear, IMHO.
      – Sergiy Kolodyazhnyy
      1 hour ago














    up vote
    3
    down vote













    Every output is written to a file anyway, I don’t know of a way not to use files. I’d use tempfiles as needed, e.g.:



    $ a=$(mktemp)
    $ b=$(mktemp)
    $ echo 1 >$a & echo 2 >$b & wait
    $ cat $b
    2
    $ cat $a
    1


    mktemp creates two tempfiles a and b, the echo commands write to the tempfiles, you can then use cat to print from them at any time you need the output. If you want to redirect both stdout and stderr, use &> instead.






    share|improve this answer






















    • Clever. Reading file descriptors in sequence you want. +1
      – Sergiy Kolodyazhnyy
      2 hours ago










    • @PerlDuck correct, I mixed up two things there
      – dessert
      1 hour ago










    • @SergiyKolodyazhnyy I didn’t manage to use fd’s here, do you know a way? However, it’s not much of a difference to tempfiles created by mktemp…
      – dessert
      1 hour ago











    • This unix.stackexchange.com/a/122101/251553 looks scary but might be adapted to the problem at hand. ;-) I haven't tried, though.
      – PerlDuck
      1 hour ago







    • 2




      @perlduck The $(...) is implemented with anonymous temp files as well, so not much difference to what dessert is doing which is much more explicit and clear, IMHO.
      – Sergiy Kolodyazhnyy
      1 hour ago












    up vote
    3
    down vote










    up vote
    3
    down vote









    Every output is written to a file anyway, I don’t know of a way not to use files. I’d use tempfiles as needed, e.g.:



    $ a=$(mktemp)
    $ b=$(mktemp)
    $ echo 1 >$a & echo 2 >$b & wait
    $ cat $b
    2
    $ cat $a
    1


    mktemp creates two tempfiles a and b, the echo commands write to the tempfiles, you can then use cat to print from them at any time you need the output. If you want to redirect both stdout and stderr, use &> instead.






    share|improve this answer














    Every output is written to a file anyway, I don’t know of a way not to use files. I’d use tempfiles as needed, e.g.:



    $ a=$(mktemp)
    $ b=$(mktemp)
    $ echo 1 >$a & echo 2 >$b & wait
    $ cat $b
    2
    $ cat $a
    1


    mktemp creates two tempfiles a and b, the echo commands write to the tempfiles, you can then use cat to print from them at any time you need the output. If you want to redirect both stdout and stderr, use &> instead.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 44 mins ago

























    answered 3 hours ago









    dessert

    20.5k55896




    20.5k55896











    • Clever. Reading file descriptors in sequence you want. +1
      – Sergiy Kolodyazhnyy
      2 hours ago










    • @PerlDuck correct, I mixed up two things there
      – dessert
      1 hour ago










    • @SergiyKolodyazhnyy I didn’t manage to use fd’s here, do you know a way? However, it’s not much of a difference to tempfiles created by mktemp…
      – dessert
      1 hour ago











    • This unix.stackexchange.com/a/122101/251553 looks scary but might be adapted to the problem at hand. ;-) I haven't tried, though.
      – PerlDuck
      1 hour ago







    • 2




      @perlduck The $(...) is implemented with anonymous temp files as well, so not much difference to what dessert is doing which is much more explicit and clear, IMHO.
      – Sergiy Kolodyazhnyy
      1 hour ago
















    • Clever. Reading file descriptors in sequence you want. +1
      – Sergiy Kolodyazhnyy
      2 hours ago










    • @PerlDuck correct, I mixed up two things there
      – dessert
      1 hour ago










    • @SergiyKolodyazhnyy I didn’t manage to use fd’s here, do you know a way? However, it’s not much of a difference to tempfiles created by mktemp…
      – dessert
      1 hour ago











    • This unix.stackexchange.com/a/122101/251553 looks scary but might be adapted to the problem at hand. ;-) I haven't tried, though.
      – PerlDuck
      1 hour ago







    • 2




      @perlduck The $(...) is implemented with anonymous temp files as well, so not much difference to what dessert is doing which is much more explicit and clear, IMHO.
      – Sergiy Kolodyazhnyy
      1 hour ago















    Clever. Reading file descriptors in sequence you want. +1
    – Sergiy Kolodyazhnyy
    2 hours ago




    Clever. Reading file descriptors in sequence you want. +1
    – Sergiy Kolodyazhnyy
    2 hours ago












    @PerlDuck correct, I mixed up two things there
    – dessert
    1 hour ago




    @PerlDuck correct, I mixed up two things there
    – dessert
    1 hour ago












    @SergiyKolodyazhnyy I didn’t manage to use fd’s here, do you know a way? However, it’s not much of a difference to tempfiles created by mktemp…
    – dessert
    1 hour ago





    @SergiyKolodyazhnyy I didn’t manage to use fd’s here, do you know a way? However, it’s not much of a difference to tempfiles created by mktemp…
    – dessert
    1 hour ago













    This unix.stackexchange.com/a/122101/251553 looks scary but might be adapted to the problem at hand. ;-) I haven't tried, though.
    – PerlDuck
    1 hour ago





    This unix.stackexchange.com/a/122101/251553 looks scary but might be adapted to the problem at hand. ;-) I haven't tried, though.
    – PerlDuck
    1 hour ago





    2




    2




    @perlduck The $(...) is implemented with anonymous temp files as well, so not much difference to what dessert is doing which is much more explicit and clear, IMHO.
    – Sergiy Kolodyazhnyy
    1 hour ago




    @perlduck The $(...) is implemented with anonymous temp files as well, so not much difference to what dessert is doing which is much more explicit and clear, IMHO.
    – Sergiy Kolodyazhnyy
    1 hour ago












    up vote
    1
    down vote













    I would like to see a complete solution, that will be efficient on large number of records. Meanwhile if you have few hundred lines or lot of time (for few hundred thousands lines) you can try something like this:





    #!/bin/bash

    # Two functions that do number of things
    foo() for i in 1..3; do echo "foo $i."; done; exit 0;
    bar() for i in 1..5; do echo "bar .$i"; done; exit 0;

    # The missing function :)
    log_cat() wc -l)" && echo "[bar lines]: $BAR_LINES"

    # Get the bigger lines number
    if (( FOO_LINES >= BAR_LINES )); then LINES="$FOO_LINES"; else LINES="$BAR_LINES"; fi

    for (( LINE=1; LINE<=LINES; LINE++ ))
    do
    # Use `sed' to `p'rint only the current $LINE from both log files;
    # `-n' will suppress the rest output of `sed':
    # sed -n "$LINE p" "$FOO_LOG" && sed -n "$LINE p" "$BAR_LOG"
    # Use the above with `printf' for better formatting
    printf 'n[foo %sn[bar %sn' "$LINE]: $(sed -n "$LINE p" "$FOO_LOG")" "$LINE]: $(sed -n "$LINE p" "$BAR_LOG")"
    done


    # Define log files
    FOO_LOG="/tmp/prefix_foo.tmp"
    BAR_LOG="/tmp/prefix_bar.tmp"

    # Execute the two functions and redirect their stdout to the log files
    foo > "$FOO_LOG" &
    bar > "$BAR_LOG" &
    wait

    # Concatenate the log files in the desired way
    log_cat


    Sample output:



    $ ./rotate.sh 
    [foo lines]: 3
    [bar lines]: 5

    [foo 1]: foo 1.
    [bar 1]: bar .1

    [foo 2]: foo 2.
    [bar 2]: bar .2

    [foo 3]: foo 3.
    [bar 3]: bar .3

    [foo 4]:
    [bar 4]: bar .4

    [foo 5]:
    [bar 5]: bar .5





    share|improve this answer






















    • @dessert, done. Thanks!
      – pa4080
      24 mins ago










    • Oh, I thought you were printing in columns, misread the printf – I think OP wanted to separate the two outputs: “all of foo's output followed by all of bar's output”
      – dessert
      16 mins ago














    up vote
    1
    down vote













    I would like to see a complete solution, that will be efficient on large number of records. Meanwhile if you have few hundred lines or lot of time (for few hundred thousands lines) you can try something like this:





    #!/bin/bash

    # Two functions that do number of things
    foo() for i in 1..3; do echo "foo $i."; done; exit 0;
    bar() for i in 1..5; do echo "bar .$i"; done; exit 0;

    # The missing function :)
    log_cat() wc -l)" && echo "[bar lines]: $BAR_LINES"

    # Get the bigger lines number
    if (( FOO_LINES >= BAR_LINES )); then LINES="$FOO_LINES"; else LINES="$BAR_LINES"; fi

    for (( LINE=1; LINE<=LINES; LINE++ ))
    do
    # Use `sed' to `p'rint only the current $LINE from both log files;
    # `-n' will suppress the rest output of `sed':
    # sed -n "$LINE p" "$FOO_LOG" && sed -n "$LINE p" "$BAR_LOG"
    # Use the above with `printf' for better formatting
    printf 'n[foo %sn[bar %sn' "$LINE]: $(sed -n "$LINE p" "$FOO_LOG")" "$LINE]: $(sed -n "$LINE p" "$BAR_LOG")"
    done


    # Define log files
    FOO_LOG="/tmp/prefix_foo.tmp"
    BAR_LOG="/tmp/prefix_bar.tmp"

    # Execute the two functions and redirect their stdout to the log files
    foo > "$FOO_LOG" &
    bar > "$BAR_LOG" &
    wait

    # Concatenate the log files in the desired way
    log_cat


    Sample output:



    $ ./rotate.sh 
    [foo lines]: 3
    [bar lines]: 5

    [foo 1]: foo 1.
    [bar 1]: bar .1

    [foo 2]: foo 2.
    [bar 2]: bar .2

    [foo 3]: foo 3.
    [bar 3]: bar .3

    [foo 4]:
    [bar 4]: bar .4

    [foo 5]:
    [bar 5]: bar .5





    share|improve this answer






















    • @dessert, done. Thanks!
      – pa4080
      24 mins ago










    • Oh, I thought you were printing in columns, misread the printf – I think OP wanted to separate the two outputs: “all of foo's output followed by all of bar's output”
      – dessert
      16 mins ago












    up vote
    1
    down vote










    up vote
    1
    down vote









    I would like to see a complete solution, that will be efficient on large number of records. Meanwhile if you have few hundred lines or lot of time (for few hundred thousands lines) you can try something like this:





    #!/bin/bash

    # Two functions that do number of things
    foo() for i in 1..3; do echo "foo $i."; done; exit 0;
    bar() for i in 1..5; do echo "bar .$i"; done; exit 0;

    # The missing function :)
    log_cat() wc -l)" && echo "[bar lines]: $BAR_LINES"

    # Get the bigger lines number
    if (( FOO_LINES >= BAR_LINES )); then LINES="$FOO_LINES"; else LINES="$BAR_LINES"; fi

    for (( LINE=1; LINE<=LINES; LINE++ ))
    do
    # Use `sed' to `p'rint only the current $LINE from both log files;
    # `-n' will suppress the rest output of `sed':
    # sed -n "$LINE p" "$FOO_LOG" && sed -n "$LINE p" "$BAR_LOG"
    # Use the above with `printf' for better formatting
    printf 'n[foo %sn[bar %sn' "$LINE]: $(sed -n "$LINE p" "$FOO_LOG")" "$LINE]: $(sed -n "$LINE p" "$BAR_LOG")"
    done


    # Define log files
    FOO_LOG="/tmp/prefix_foo.tmp"
    BAR_LOG="/tmp/prefix_bar.tmp"

    # Execute the two functions and redirect their stdout to the log files
    foo > "$FOO_LOG" &
    bar > "$BAR_LOG" &
    wait

    # Concatenate the log files in the desired way
    log_cat


    Sample output:



    $ ./rotate.sh 
    [foo lines]: 3
    [bar lines]: 5

    [foo 1]: foo 1.
    [bar 1]: bar .1

    [foo 2]: foo 2.
    [bar 2]: bar .2

    [foo 3]: foo 3.
    [bar 3]: bar .3

    [foo 4]:
    [bar 4]: bar .4

    [foo 5]:
    [bar 5]: bar .5





    share|improve this answer














    I would like to see a complete solution, that will be efficient on large number of records. Meanwhile if you have few hundred lines or lot of time (for few hundred thousands lines) you can try something like this:





    #!/bin/bash

    # Two functions that do number of things
    foo() for i in 1..3; do echo "foo $i."; done; exit 0;
    bar() for i in 1..5; do echo "bar .$i"; done; exit 0;

    # The missing function :)
    log_cat() wc -l)" && echo "[bar lines]: $BAR_LINES"

    # Get the bigger lines number
    if (( FOO_LINES >= BAR_LINES )); then LINES="$FOO_LINES"; else LINES="$BAR_LINES"; fi

    for (( LINE=1; LINE<=LINES; LINE++ ))
    do
    # Use `sed' to `p'rint only the current $LINE from both log files;
    # `-n' will suppress the rest output of `sed':
    # sed -n "$LINE p" "$FOO_LOG" && sed -n "$LINE p" "$BAR_LOG"
    # Use the above with `printf' for better formatting
    printf 'n[foo %sn[bar %sn' "$LINE]: $(sed -n "$LINE p" "$FOO_LOG")" "$LINE]: $(sed -n "$LINE p" "$BAR_LOG")"
    done


    # Define log files
    FOO_LOG="/tmp/prefix_foo.tmp"
    BAR_LOG="/tmp/prefix_bar.tmp"

    # Execute the two functions and redirect their stdout to the log files
    foo > "$FOO_LOG" &
    bar > "$BAR_LOG" &
    wait

    # Concatenate the log files in the desired way
    log_cat


    Sample output:



    $ ./rotate.sh 
    [foo lines]: 3
    [bar lines]: 5

    [foo 1]: foo 1.
    [bar 1]: bar .1

    [foo 2]: foo 2.
    [bar 2]: bar .2

    [foo 3]: foo 3.
    [bar 3]: bar .3

    [foo 4]:
    [bar 4]: bar .4

    [foo 5]:
    [bar 5]: bar .5






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 19 mins ago

























    answered 34 mins ago









    pa4080

    12.6k52358




    12.6k52358











    • @dessert, done. Thanks!
      – pa4080
      24 mins ago










    • Oh, I thought you were printing in columns, misread the printf – I think OP wanted to separate the two outputs: “all of foo's output followed by all of bar's output”
      – dessert
      16 mins ago
















    • @dessert, done. Thanks!
      – pa4080
      24 mins ago










    • Oh, I thought you were printing in columns, misread the printf – I think OP wanted to separate the two outputs: “all of foo's output followed by all of bar's output”
      – dessert
      16 mins ago















    @dessert, done. Thanks!
    – pa4080
    24 mins ago




    @dessert, done. Thanks!
    – pa4080
    24 mins ago












    Oh, I thought you were printing in columns, misread the printf – I think OP wanted to separate the two outputs: “all of foo's output followed by all of bar's output”
    – dessert
    16 mins ago




    Oh, I thought you were printing in columns, misread the printf – I think OP wanted to separate the two outputs: “all of foo's output followed by all of bar's output”
    – dessert
    16 mins ago










    up vote
    0
    down vote













    Well, the system is writing to files anyway to accomplish this; they're just temp files. However, you could have the foo process output to one file and rename it when complete. Have bar watch for the rename of said file, and when foo completes the rename, bar outputs the foo output then prints its own output, a la:



    function foo 
    # do a bunch of things
    # print a lot of output to /tmp/foo.work
    # mv /tmp/foo.work /tmp/foo.done


    function bar
    # do more things
    # write more things to /tmp/bar.done
    # if exist /tmp/foo.done print /tmp/foo.done else wait 1 and recheck
    # rm /tmp/foo.done
    # print /tmp/bar.done






    share|improve this answer


























      up vote
      0
      down vote













      Well, the system is writing to files anyway to accomplish this; they're just temp files. However, you could have the foo process output to one file and rename it when complete. Have bar watch for the rename of said file, and when foo completes the rename, bar outputs the foo output then prints its own output, a la:



      function foo 
      # do a bunch of things
      # print a lot of output to /tmp/foo.work
      # mv /tmp/foo.work /tmp/foo.done


      function bar
      # do more things
      # write more things to /tmp/bar.done
      # if exist /tmp/foo.done print /tmp/foo.done else wait 1 and recheck
      # rm /tmp/foo.done
      # print /tmp/bar.done






      share|improve this answer
























        up vote
        0
        down vote










        up vote
        0
        down vote









        Well, the system is writing to files anyway to accomplish this; they're just temp files. However, you could have the foo process output to one file and rename it when complete. Have bar watch for the rename of said file, and when foo completes the rename, bar outputs the foo output then prints its own output, a la:



        function foo 
        # do a bunch of things
        # print a lot of output to /tmp/foo.work
        # mv /tmp/foo.work /tmp/foo.done


        function bar
        # do more things
        # write more things to /tmp/bar.done
        # if exist /tmp/foo.done print /tmp/foo.done else wait 1 and recheck
        # rm /tmp/foo.done
        # print /tmp/bar.done






        share|improve this answer














        Well, the system is writing to files anyway to accomplish this; they're just temp files. However, you could have the foo process output to one file and rename it when complete. Have bar watch for the rename of said file, and when foo completes the rename, bar outputs the foo output then prints its own output, a la:



        function foo 
        # do a bunch of things
        # print a lot of output to /tmp/foo.work
        # mv /tmp/foo.work /tmp/foo.done


        function bar
        # do more things
        # write more things to /tmp/bar.done
        # if exist /tmp/foo.done print /tmp/foo.done else wait 1 and recheck
        # rm /tmp/foo.done
        # print /tmp/bar.done







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 3 hours ago

























        answered 3 hours ago









        K7AAY

        3,84221543




        3,84221543




















            D Day is a new contributor. Be nice, and check out our Code of Conduct.









             

            draft saved


            draft discarded


















            D Day is a new contributor. Be nice, and check out our Code of Conduct.












            D Day is a new contributor. Be nice, and check out our Code of Conduct.











            D Day is a new contributor. Be nice, and check out our Code of Conduct.













             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1089250%2fwant-to-print-output-of-two-background-shell-functions-sequentially%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            What does second last employer means? [closed]

            Installing NextGIS Connect into QGIS 3?

            One-line joke