docker-compose, less and SIGINT

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 a script that boots up a test environment using docker-compose.
This script pipes the mixed stdout of many docker containers on stdout through less:





# This is part of a larger script with some setup and teardown.
$ docker-compose up --build | less +F -r


less shows an undesired behavior here: When hitting CTRL-C, docker-compose receives it and shuts down itself. Desired behaviour is only to interrupt the following (+F) feature of less (like it does when viewing e.g. a large log).



What I want to achieve in the optimal case:
Interrupt the following with the first CTRL-C and quit the whole test environment on the second CTRL-C.



I've toyed a bit around and tried the following things:



  • Register a trap 'do_exit' SIGINT that would implement the logic above. docker-compose however still exited upon CTRL-C.

  • Use trap '' SIGINT to catch SIGNT totally. docker-compose however still got the CTRL-C out of thin air.

Another observation:



This works in zsh: (trap '' SIGINT && docker-compose up --build | less +F -r) (it does not react to SIGINT at all)
The same line behaves differently in bash and is killed by SIGINT.



Here is the full (buggy) script for reference:



#!/usr/bin/env bash

service_name=xxx

for dir in ../1 ../2 ../3; do
if [ ! -d "$dir" ]; then
echo "docker compose requires $dir, please check $dir do exist in the same folder level"
exit 0
fi
done

docker-compose up --build | less +F -r

if [ ! $? -eq 0 ]; then
echo "Couldn't start service or Control-C was pressed"
echo "cleaning up"
docker-compose down
exit $?
fi

docker-compose rm --all --force


Any solution or experiences with this?



--



Edit: I've also tried the solutions here without any success:



  • Is there any way to exit “less” follow mode without stopping other processes in pipe?

  • Follow a pipe using less?






share|improve this question






















  • pkill -INT less from another terminal?
    – muru
    Mar 6 at 10:09










  • Thanks @muru, pkill -INT less kind of works (only kills less, but not docker-compose), but doesn't really answer the question. Preferably I want to be able to hit Ctrl-C directly in the terminal out of convinience (and I also want to understand how this works...)
    – Sahib
    Mar 6 at 10:50










  • Have you tried (trap '' INT && docker-compose up --build) | less +F -R?
    – Stéphane Chazelas
    Mar 6 at 11:43











  • Note that your script will also get the SIGINT
    – Stéphane Chazelas
    Mar 6 at 11:44










  • @StéphaneChazelas: Thanks. Still pressing CTRL-C will stop docker-compose, while it should only stop the paging mode of less. Can you explain why (docker-compose up --build | less +F -r) is not interruptable in zsh and but is in bash?
    – Sahib
    Mar 6 at 12:31














up vote
1
down vote

favorite












I have a script that boots up a test environment using docker-compose.
This script pipes the mixed stdout of many docker containers on stdout through less:





# This is part of a larger script with some setup and teardown.
$ docker-compose up --build | less +F -r


less shows an undesired behavior here: When hitting CTRL-C, docker-compose receives it and shuts down itself. Desired behaviour is only to interrupt the following (+F) feature of less (like it does when viewing e.g. a large log).



What I want to achieve in the optimal case:
Interrupt the following with the first CTRL-C and quit the whole test environment on the second CTRL-C.



I've toyed a bit around and tried the following things:



  • Register a trap 'do_exit' SIGINT that would implement the logic above. docker-compose however still exited upon CTRL-C.

  • Use trap '' SIGINT to catch SIGNT totally. docker-compose however still got the CTRL-C out of thin air.

Another observation:



This works in zsh: (trap '' SIGINT && docker-compose up --build | less +F -r) (it does not react to SIGINT at all)
The same line behaves differently in bash and is killed by SIGINT.



Here is the full (buggy) script for reference:



#!/usr/bin/env bash

service_name=xxx

for dir in ../1 ../2 ../3; do
if [ ! -d "$dir" ]; then
echo "docker compose requires $dir, please check $dir do exist in the same folder level"
exit 0
fi
done

docker-compose up --build | less +F -r

if [ ! $? -eq 0 ]; then
echo "Couldn't start service or Control-C was pressed"
echo "cleaning up"
docker-compose down
exit $?
fi

docker-compose rm --all --force


Any solution or experiences with this?



--



Edit: I've also tried the solutions here without any success:



  • Is there any way to exit “less” follow mode without stopping other processes in pipe?

  • Follow a pipe using less?






share|improve this question






















  • pkill -INT less from another terminal?
    – muru
    Mar 6 at 10:09










  • Thanks @muru, pkill -INT less kind of works (only kills less, but not docker-compose), but doesn't really answer the question. Preferably I want to be able to hit Ctrl-C directly in the terminal out of convinience (and I also want to understand how this works...)
    – Sahib
    Mar 6 at 10:50










  • Have you tried (trap '' INT && docker-compose up --build) | less +F -R?
    – Stéphane Chazelas
    Mar 6 at 11:43











  • Note that your script will also get the SIGINT
    – Stéphane Chazelas
    Mar 6 at 11:44










  • @StéphaneChazelas: Thanks. Still pressing CTRL-C will stop docker-compose, while it should only stop the paging mode of less. Can you explain why (docker-compose up --build | less +F -r) is not interruptable in zsh and but is in bash?
    – Sahib
    Mar 6 at 12:31












up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have a script that boots up a test environment using docker-compose.
This script pipes the mixed stdout of many docker containers on stdout through less:





# This is part of a larger script with some setup and teardown.
$ docker-compose up --build | less +F -r


less shows an undesired behavior here: When hitting CTRL-C, docker-compose receives it and shuts down itself. Desired behaviour is only to interrupt the following (+F) feature of less (like it does when viewing e.g. a large log).



What I want to achieve in the optimal case:
Interrupt the following with the first CTRL-C and quit the whole test environment on the second CTRL-C.



I've toyed a bit around and tried the following things:



  • Register a trap 'do_exit' SIGINT that would implement the logic above. docker-compose however still exited upon CTRL-C.

  • Use trap '' SIGINT to catch SIGNT totally. docker-compose however still got the CTRL-C out of thin air.

Another observation:



This works in zsh: (trap '' SIGINT && docker-compose up --build | less +F -r) (it does not react to SIGINT at all)
The same line behaves differently in bash and is killed by SIGINT.



Here is the full (buggy) script for reference:



#!/usr/bin/env bash

service_name=xxx

for dir in ../1 ../2 ../3; do
if [ ! -d "$dir" ]; then
echo "docker compose requires $dir, please check $dir do exist in the same folder level"
exit 0
fi
done

docker-compose up --build | less +F -r

if [ ! $? -eq 0 ]; then
echo "Couldn't start service or Control-C was pressed"
echo "cleaning up"
docker-compose down
exit $?
fi

docker-compose rm --all --force


Any solution or experiences with this?



--



Edit: I've also tried the solutions here without any success:



  • Is there any way to exit “less” follow mode without stopping other processes in pipe?

  • Follow a pipe using less?






share|improve this question














I have a script that boots up a test environment using docker-compose.
This script pipes the mixed stdout of many docker containers on stdout through less:





# This is part of a larger script with some setup and teardown.
$ docker-compose up --build | less +F -r


less shows an undesired behavior here: When hitting CTRL-C, docker-compose receives it and shuts down itself. Desired behaviour is only to interrupt the following (+F) feature of less (like it does when viewing e.g. a large log).



What I want to achieve in the optimal case:
Interrupt the following with the first CTRL-C and quit the whole test environment on the second CTRL-C.



I've toyed a bit around and tried the following things:



  • Register a trap 'do_exit' SIGINT that would implement the logic above. docker-compose however still exited upon CTRL-C.

  • Use trap '' SIGINT to catch SIGNT totally. docker-compose however still got the CTRL-C out of thin air.

Another observation:



This works in zsh: (trap '' SIGINT && docker-compose up --build | less +F -r) (it does not react to SIGINT at all)
The same line behaves differently in bash and is killed by SIGINT.



Here is the full (buggy) script for reference:



#!/usr/bin/env bash

service_name=xxx

for dir in ../1 ../2 ../3; do
if [ ! -d "$dir" ]; then
echo "docker compose requires $dir, please check $dir do exist in the same folder level"
exit 0
fi
done

docker-compose up --build | less +F -r

if [ ! $? -eq 0 ]; then
echo "Couldn't start service or Control-C was pressed"
echo "cleaning up"
docker-compose down
exit $?
fi

docker-compose rm --all --force


Any solution or experiences with this?



--



Edit: I've also tried the solutions here without any success:



  • Is there any way to exit “less” follow mode without stopping other processes in pipe?

  • Follow a pipe using less?








share|improve this question













share|improve this question




share|improve this question








edited Mar 6 at 11:00

























asked Mar 6 at 10:04









Sahib

63




63











  • pkill -INT less from another terminal?
    – muru
    Mar 6 at 10:09










  • Thanks @muru, pkill -INT less kind of works (only kills less, but not docker-compose), but doesn't really answer the question. Preferably I want to be able to hit Ctrl-C directly in the terminal out of convinience (and I also want to understand how this works...)
    – Sahib
    Mar 6 at 10:50










  • Have you tried (trap '' INT && docker-compose up --build) | less +F -R?
    – Stéphane Chazelas
    Mar 6 at 11:43











  • Note that your script will also get the SIGINT
    – Stéphane Chazelas
    Mar 6 at 11:44










  • @StéphaneChazelas: Thanks. Still pressing CTRL-C will stop docker-compose, while it should only stop the paging mode of less. Can you explain why (docker-compose up --build | less +F -r) is not interruptable in zsh and but is in bash?
    – Sahib
    Mar 6 at 12:31
















  • pkill -INT less from another terminal?
    – muru
    Mar 6 at 10:09










  • Thanks @muru, pkill -INT less kind of works (only kills less, but not docker-compose), but doesn't really answer the question. Preferably I want to be able to hit Ctrl-C directly in the terminal out of convinience (and I also want to understand how this works...)
    – Sahib
    Mar 6 at 10:50










  • Have you tried (trap '' INT && docker-compose up --build) | less +F -R?
    – Stéphane Chazelas
    Mar 6 at 11:43











  • Note that your script will also get the SIGINT
    – Stéphane Chazelas
    Mar 6 at 11:44










  • @StéphaneChazelas: Thanks. Still pressing CTRL-C will stop docker-compose, while it should only stop the paging mode of less. Can you explain why (docker-compose up --build | less +F -r) is not interruptable in zsh and but is in bash?
    – Sahib
    Mar 6 at 12:31















pkill -INT less from another terminal?
– muru
Mar 6 at 10:09




pkill -INT less from another terminal?
– muru
Mar 6 at 10:09












Thanks @muru, pkill -INT less kind of works (only kills less, but not docker-compose), but doesn't really answer the question. Preferably I want to be able to hit Ctrl-C directly in the terminal out of convinience (and I also want to understand how this works...)
– Sahib
Mar 6 at 10:50




Thanks @muru, pkill -INT less kind of works (only kills less, but not docker-compose), but doesn't really answer the question. Preferably I want to be able to hit Ctrl-C directly in the terminal out of convinience (and I also want to understand how this works...)
– Sahib
Mar 6 at 10:50












Have you tried (trap '' INT && docker-compose up --build) | less +F -R?
– Stéphane Chazelas
Mar 6 at 11:43





Have you tried (trap '' INT && docker-compose up --build) | less +F -R?
– Stéphane Chazelas
Mar 6 at 11:43













Note that your script will also get the SIGINT
– Stéphane Chazelas
Mar 6 at 11:44




Note that your script will also get the SIGINT
– Stéphane Chazelas
Mar 6 at 11:44












@StéphaneChazelas: Thanks. Still pressing CTRL-C will stop docker-compose, while it should only stop the paging mode of less. Can you explain why (docker-compose up --build | less +F -r) is not interruptable in zsh and but is in bash?
– Sahib
Mar 6 at 12:31




@StéphaneChazelas: Thanks. Still pressing CTRL-C will stop docker-compose, while it should only stop the paging mode of less. Can you explain why (docker-compose up --build | less +F -r) is not interruptable in zsh and but is in bash?
– Sahib
Mar 6 at 12:31










1 Answer
1






active

oldest

votes

















up vote
0
down vote



accepted










I figured it out after reading this:



  • https://en.wikipedia.org/wiki/Process_group

  • https://www.gnu.org/software/bash/manual/html_node/Job-Control.html#Job-Control

The solution is to do set -m at the start of the script.
This causes bash to create a new process group for each process,
not causing SIGINT to be send to every process in the script.



For reference, the fixed script looks like this:



#!/usr/bin/env bash

set -m
set -e

service_name=xxx

for dir in ../1 ../2 ../3; do
if [ ! -d "$dir" ]; then
echo "docker compose requires $dir, please check $dir do exist in the same folder level"
exit 0
fi
done

TEMP_LOG_FILE=$(mktemp --suffix '-dev-env-log')
(trap '' SIGINT && docker-compose up --build > $TEMP_LOG_FILE) &
less +F -r $TEMP_LOG_FILE
rm $TEMP_LOG_FILE

echo "Less was quit, stopping containers..."


if [ ! $? -eq 0 ]; then
echo "could not start service or Control-C was pressed"
echo "cleaning up"
docker-compose down
exit $?
fi

docker-compose down
docker-compose rm --all --force





share|improve this answer




















    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    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: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f428456%2fdocker-compose-less-and-sigint%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote



    accepted










    I figured it out after reading this:



    • https://en.wikipedia.org/wiki/Process_group

    • https://www.gnu.org/software/bash/manual/html_node/Job-Control.html#Job-Control

    The solution is to do set -m at the start of the script.
    This causes bash to create a new process group for each process,
    not causing SIGINT to be send to every process in the script.



    For reference, the fixed script looks like this:



    #!/usr/bin/env bash

    set -m
    set -e

    service_name=xxx

    for dir in ../1 ../2 ../3; do
    if [ ! -d "$dir" ]; then
    echo "docker compose requires $dir, please check $dir do exist in the same folder level"
    exit 0
    fi
    done

    TEMP_LOG_FILE=$(mktemp --suffix '-dev-env-log')
    (trap '' SIGINT && docker-compose up --build > $TEMP_LOG_FILE) &
    less +F -r $TEMP_LOG_FILE
    rm $TEMP_LOG_FILE

    echo "Less was quit, stopping containers..."


    if [ ! $? -eq 0 ]; then
    echo "could not start service or Control-C was pressed"
    echo "cleaning up"
    docker-compose down
    exit $?
    fi

    docker-compose down
    docker-compose rm --all --force





    share|improve this answer
























      up vote
      0
      down vote



      accepted










      I figured it out after reading this:



      • https://en.wikipedia.org/wiki/Process_group

      • https://www.gnu.org/software/bash/manual/html_node/Job-Control.html#Job-Control

      The solution is to do set -m at the start of the script.
      This causes bash to create a new process group for each process,
      not causing SIGINT to be send to every process in the script.



      For reference, the fixed script looks like this:



      #!/usr/bin/env bash

      set -m
      set -e

      service_name=xxx

      for dir in ../1 ../2 ../3; do
      if [ ! -d "$dir" ]; then
      echo "docker compose requires $dir, please check $dir do exist in the same folder level"
      exit 0
      fi
      done

      TEMP_LOG_FILE=$(mktemp --suffix '-dev-env-log')
      (trap '' SIGINT && docker-compose up --build > $TEMP_LOG_FILE) &
      less +F -r $TEMP_LOG_FILE
      rm $TEMP_LOG_FILE

      echo "Less was quit, stopping containers..."


      if [ ! $? -eq 0 ]; then
      echo "could not start service or Control-C was pressed"
      echo "cleaning up"
      docker-compose down
      exit $?
      fi

      docker-compose down
      docker-compose rm --all --force





      share|improve this answer






















        up vote
        0
        down vote



        accepted







        up vote
        0
        down vote



        accepted






        I figured it out after reading this:



        • https://en.wikipedia.org/wiki/Process_group

        • https://www.gnu.org/software/bash/manual/html_node/Job-Control.html#Job-Control

        The solution is to do set -m at the start of the script.
        This causes bash to create a new process group for each process,
        not causing SIGINT to be send to every process in the script.



        For reference, the fixed script looks like this:



        #!/usr/bin/env bash

        set -m
        set -e

        service_name=xxx

        for dir in ../1 ../2 ../3; do
        if [ ! -d "$dir" ]; then
        echo "docker compose requires $dir, please check $dir do exist in the same folder level"
        exit 0
        fi
        done

        TEMP_LOG_FILE=$(mktemp --suffix '-dev-env-log')
        (trap '' SIGINT && docker-compose up --build > $TEMP_LOG_FILE) &
        less +F -r $TEMP_LOG_FILE
        rm $TEMP_LOG_FILE

        echo "Less was quit, stopping containers..."


        if [ ! $? -eq 0 ]; then
        echo "could not start service or Control-C was pressed"
        echo "cleaning up"
        docker-compose down
        exit $?
        fi

        docker-compose down
        docker-compose rm --all --force





        share|improve this answer












        I figured it out after reading this:



        • https://en.wikipedia.org/wiki/Process_group

        • https://www.gnu.org/software/bash/manual/html_node/Job-Control.html#Job-Control

        The solution is to do set -m at the start of the script.
        This causes bash to create a new process group for each process,
        not causing SIGINT to be send to every process in the script.



        For reference, the fixed script looks like this:



        #!/usr/bin/env bash

        set -m
        set -e

        service_name=xxx

        for dir in ../1 ../2 ../3; do
        if [ ! -d "$dir" ]; then
        echo "docker compose requires $dir, please check $dir do exist in the same folder level"
        exit 0
        fi
        done

        TEMP_LOG_FILE=$(mktemp --suffix '-dev-env-log')
        (trap '' SIGINT && docker-compose up --build > $TEMP_LOG_FILE) &
        less +F -r $TEMP_LOG_FILE
        rm $TEMP_LOG_FILE

        echo "Less was quit, stopping containers..."


        if [ ! $? -eq 0 ]; then
        echo "could not start service or Control-C was pressed"
        echo "cleaning up"
        docker-compose down
        exit $?
        fi

        docker-compose down
        docker-compose rm --all --force






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 6 at 13:37









        Sahib

        63




        63






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f428456%2fdocker-compose-less-and-sigint%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay