Emit zero-width bash prompt sequence from external binaryChanging the bash promptNew bash prompt causing...

Do objects in the public view need licencing?

Do commercial flights continue with an engine out?

Visa application for Canada: Should douments in the local language of the consulate's location be translated?

What is better: yes / no radio, or simple checkbox?

Can I become debt free or should I file for bankruptcy? How do I manage my debt and finances?

Can the SpaceX Dragon 2 crew vehicle still use the draco and super draco thrusters to slow down when landing?

How to prepare vegetables for a sandwich that can last for several days in a fridge?

Is the theory of the category of topological spaces computable?

How large should photos on my blog be?

Do my Windows system binaries contain sensitive information?

What does Matthew mean by "those on His left" and "and those on His right" in Matthew 25?

c++ How can I make an algorithm for finding variations of a set without repetition (i.e. n elements, choose k)?

Cyclical Argument in Plato's Phaedo

Criticizing long fiction. How is it different from short?

Protecting the tops of deck joists - or not?

How to satisfy a player character's curiosity about another player character?

How do I make a gun alignment to camera matrix in OpenGL GLSL?

On what did Lego base the appearance of the new Hogwarts minifigs?

Finding the number of integers that are a square and a cube at the same time

Quenching swords in dragon blood; why?

How to roast potatoes in the oven to make them crispy?

What is the purpose of easy combat scenarios that don't need resource expenditure?

Can a person refuse a presidential pardon?

Why can I easily sing or whistle a tune I've just heard, but not as easily reproduce it on an instrument?



Emit zero-width bash prompt sequence from external binary


Changing the bash promptNew bash prompt causing issuesbash - complex promptBackspace deletes Bash promptNon-printing escape sequence: when?Shell script `rm -r`: Redirect write-protected prompt and answer “n”bash: The prompt gets visually brokenbash: how to save state on prompt evaluationHighlight current bash prompt linebash prompt messed up













5















In bash, how do I encode zero-width sequences into PS1, when those sequences are coming from stdout of an external process or function? How do I implement writes-prompt-sequences-to-stdout so that it can emit multi-colored text to the prompt?



PS1='$( writes-prompt-sequences-to-stdout )'





I know that, when writing a bash PS1 prompt, I must wrap zero-width sequences in [ ] so bash can compute correct prompt width.



PS1='[e[0;35m]$ [e[00m]' bash does not print the [ ] and understands the prompt is only 2 characters wide.



How do I move those sequences into an external function? The following does not work, my prompt looks like []$ [], even though I can run render-prompt and see it writing the correct sequence of bytes to stdout.



PS1='$( render-prompt )'
function render-prompt {
printf '[e[0;35m]$ [e[00m]'
}


Moving the printf call into PS1 does work:



PS1='$( printf '"'"'[e[0;35m]$ [e[00m]'"'"' )'


I theorized, perhaps bash is scanning the PS1 string before execution to count the number of zero-width bytes. So I tried tricking it by encoding [] sequences that aren't printed, but it correctly ignores the trick.



PS1='$( printf '"'"'$$$$$'"'"' '"'"'[e[00m]'"'"' )'


My question:



How do I write [ ] sequences to stdout from a function or binary that is invoked via PS1?










share|improve this question









New contributor




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

























    5















    In bash, how do I encode zero-width sequences into PS1, when those sequences are coming from stdout of an external process or function? How do I implement writes-prompt-sequences-to-stdout so that it can emit multi-colored text to the prompt?



    PS1='$( writes-prompt-sequences-to-stdout )'





    I know that, when writing a bash PS1 prompt, I must wrap zero-width sequences in [ ] so bash can compute correct prompt width.



    PS1='[e[0;35m]$ [e[00m]' bash does not print the [ ] and understands the prompt is only 2 characters wide.



    How do I move those sequences into an external function? The following does not work, my prompt looks like []$ [], even though I can run render-prompt and see it writing the correct sequence of bytes to stdout.



    PS1='$( render-prompt )'
    function render-prompt {
    printf '[e[0;35m]$ [e[00m]'
    }


    Moving the printf call into PS1 does work:



    PS1='$( printf '"'"'[e[0;35m]$ [e[00m]'"'"' )'


    I theorized, perhaps bash is scanning the PS1 string before execution to count the number of zero-width bytes. So I tried tricking it by encoding [] sequences that aren't printed, but it correctly ignores the trick.



    PS1='$( printf '"'"'$$$$$'"'"' '"'"'[e[00m]'"'"' )'


    My question:



    How do I write [ ] sequences to stdout from a function or binary that is invoked via PS1?










    share|improve this question









    New contributor




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























      5












      5








      5








      In bash, how do I encode zero-width sequences into PS1, when those sequences are coming from stdout of an external process or function? How do I implement writes-prompt-sequences-to-stdout so that it can emit multi-colored text to the prompt?



      PS1='$( writes-prompt-sequences-to-stdout )'





      I know that, when writing a bash PS1 prompt, I must wrap zero-width sequences in [ ] so bash can compute correct prompt width.



      PS1='[e[0;35m]$ [e[00m]' bash does not print the [ ] and understands the prompt is only 2 characters wide.



      How do I move those sequences into an external function? The following does not work, my prompt looks like []$ [], even though I can run render-prompt and see it writing the correct sequence of bytes to stdout.



      PS1='$( render-prompt )'
      function render-prompt {
      printf '[e[0;35m]$ [e[00m]'
      }


      Moving the printf call into PS1 does work:



      PS1='$( printf '"'"'[e[0;35m]$ [e[00m]'"'"' )'


      I theorized, perhaps bash is scanning the PS1 string before execution to count the number of zero-width bytes. So I tried tricking it by encoding [] sequences that aren't printed, but it correctly ignores the trick.



      PS1='$( printf '"'"'$$$$$'"'"' '"'"'[e[00m]'"'"' )'


      My question:



      How do I write [ ] sequences to stdout from a function or binary that is invoked via PS1?










      share|improve this question









      New contributor




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












      In bash, how do I encode zero-width sequences into PS1, when those sequences are coming from stdout of an external process or function? How do I implement writes-prompt-sequences-to-stdout so that it can emit multi-colored text to the prompt?



      PS1='$( writes-prompt-sequences-to-stdout )'





      I know that, when writing a bash PS1 prompt, I must wrap zero-width sequences in [ ] so bash can compute correct prompt width.



      PS1='[e[0;35m]$ [e[00m]' bash does not print the [ ] and understands the prompt is only 2 characters wide.



      How do I move those sequences into an external function? The following does not work, my prompt looks like []$ [], even though I can run render-prompt and see it writing the correct sequence of bytes to stdout.



      PS1='$( render-prompt )'
      function render-prompt {
      printf '[e[0;35m]$ [e[00m]'
      }


      Moving the printf call into PS1 does work:



      PS1='$( printf '"'"'[e[0;35m]$ [e[00m]'"'"' )'


      I theorized, perhaps bash is scanning the PS1 string before execution to count the number of zero-width bytes. So I tried tricking it by encoding [] sequences that aren't printed, but it correctly ignores the trick.



      PS1='$( printf '"'"'$$$$$'"'"' '"'"'[e[00m]'"'"' )'


      My question:



      How do I write [ ] sequences to stdout from a function or binary that is invoked via PS1?







      bash prompt






      share|improve this question









      New contributor




      cspotcode 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




      cspotcode 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 2 hours ago









      Jeff Schaller

      42.9k1159137




      42.9k1159137






      New contributor




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









      asked 3 hours ago









      cspotcodecspotcode

      1462




      1462




      New contributor




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





      New contributor





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






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






















          2 Answers
          2






          active

          oldest

          votes


















          2














          I figured it out. Bash special-cases e, [, and ] within PS1. It coverts e to an escape byte, [ to a 1 byte, and ] to a 2 byte. External commands must write 1 and 2 bytes to stdout.



          According to ASCII, these encode "start of heading" and "start of text."



          http://www.columbia.edu/kermit/ascii.html



          Here's a working example, which relies on printf converting escapes within the first positional parameter into the correct bytes:



          PS1='$( render-prompt )'
          function render-prompt {
          printf '133[0;35m2$ 133[00m2'
          }


          render-prompt | hexdump -C


          00000000  01 1b 5b 30 3b 33 35 6d  02 24 20 01 1b 5b 30 30  |..[0;35m.$ ..[00|
          00000010 6d 02 |m.|
          00000012





          share|improve this answer








          New contributor




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




























            0














            You correctly figured out the 1, 2 and e. But there's a better and more correct way to produce the sequences.



            The printf command takes FORMAT as the first argument. This format consumes the subsequent arguments. So your function could be better written this way:



            render-prompt () { printf "1%b2%s1%b2" 'e[0;35m' '$ ' 'e[00m'; }


            The first argument is "1%b2%s1%b2" and this is the format. It's a good and logical place for 1 and 2, which embrace the %b parameters. (The %bs are -escaped strings and %s represents a standard string.)



            The others are 'e[0;35m', '$ ' and 'e[00m', which correspond to %b, %s and %b in the format. Here I'd put es, as they escape the [ braces they precede.






            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',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              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
              });


              }
              });






              cspotcode 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%2funix.stackexchange.com%2fquestions%2f504150%2femit-zero-width-bash-prompt-sequence-from-external-binary%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              2














              I figured it out. Bash special-cases e, [, and ] within PS1. It coverts e to an escape byte, [ to a 1 byte, and ] to a 2 byte. External commands must write 1 and 2 bytes to stdout.



              According to ASCII, these encode "start of heading" and "start of text."



              http://www.columbia.edu/kermit/ascii.html



              Here's a working example, which relies on printf converting escapes within the first positional parameter into the correct bytes:



              PS1='$( render-prompt )'
              function render-prompt {
              printf '133[0;35m2$ 133[00m2'
              }


              render-prompt | hexdump -C


              00000000  01 1b 5b 30 3b 33 35 6d  02 24 20 01 1b 5b 30 30  |..[0;35m.$ ..[00|
              00000010 6d 02 |m.|
              00000012





              share|improve this answer








              New contributor




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

























                2














                I figured it out. Bash special-cases e, [, and ] within PS1. It coverts e to an escape byte, [ to a 1 byte, and ] to a 2 byte. External commands must write 1 and 2 bytes to stdout.



                According to ASCII, these encode "start of heading" and "start of text."



                http://www.columbia.edu/kermit/ascii.html



                Here's a working example, which relies on printf converting escapes within the first positional parameter into the correct bytes:



                PS1='$( render-prompt )'
                function render-prompt {
                printf '133[0;35m2$ 133[00m2'
                }


                render-prompt | hexdump -C


                00000000  01 1b 5b 30 3b 33 35 6d  02 24 20 01 1b 5b 30 30  |..[0;35m.$ ..[00|
                00000010 6d 02 |m.|
                00000012





                share|improve this answer








                New contributor




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























                  2












                  2








                  2







                  I figured it out. Bash special-cases e, [, and ] within PS1. It coverts e to an escape byte, [ to a 1 byte, and ] to a 2 byte. External commands must write 1 and 2 bytes to stdout.



                  According to ASCII, these encode "start of heading" and "start of text."



                  http://www.columbia.edu/kermit/ascii.html



                  Here's a working example, which relies on printf converting escapes within the first positional parameter into the correct bytes:



                  PS1='$( render-prompt )'
                  function render-prompt {
                  printf '133[0;35m2$ 133[00m2'
                  }


                  render-prompt | hexdump -C


                  00000000  01 1b 5b 30 3b 33 35 6d  02 24 20 01 1b 5b 30 30  |..[0;35m.$ ..[00|
                  00000010 6d 02 |m.|
                  00000012





                  share|improve this answer








                  New contributor




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










                  I figured it out. Bash special-cases e, [, and ] within PS1. It coverts e to an escape byte, [ to a 1 byte, and ] to a 2 byte. External commands must write 1 and 2 bytes to stdout.



                  According to ASCII, these encode "start of heading" and "start of text."



                  http://www.columbia.edu/kermit/ascii.html



                  Here's a working example, which relies on printf converting escapes within the first positional parameter into the correct bytes:



                  PS1='$( render-prompt )'
                  function render-prompt {
                  printf '133[0;35m2$ 133[00m2'
                  }


                  render-prompt | hexdump -C


                  00000000  01 1b 5b 30 3b 33 35 6d  02 24 20 01 1b 5b 30 30  |..[0;35m.$ ..[00|
                  00000010 6d 02 |m.|
                  00000012






                  share|improve this answer








                  New contributor




                  cspotcode 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 answer



                  share|improve this answer






                  New contributor




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









                  answered 2 hours ago









                  cspotcodecspotcode

                  1462




                  1462




                  New contributor




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





                  New contributor





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






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

























                      0














                      You correctly figured out the 1, 2 and e. But there's a better and more correct way to produce the sequences.



                      The printf command takes FORMAT as the first argument. This format consumes the subsequent arguments. So your function could be better written this way:



                      render-prompt () { printf "1%b2%s1%b2" 'e[0;35m' '$ ' 'e[00m'; }


                      The first argument is "1%b2%s1%b2" and this is the format. It's a good and logical place for 1 and 2, which embrace the %b parameters. (The %bs are -escaped strings and %s represents a standard string.)



                      The others are 'e[0;35m', '$ ' and 'e[00m', which correspond to %b, %s and %b in the format. Here I'd put es, as they escape the [ braces they precede.






                      share|improve this answer




























                        0














                        You correctly figured out the 1, 2 and e. But there's a better and more correct way to produce the sequences.



                        The printf command takes FORMAT as the first argument. This format consumes the subsequent arguments. So your function could be better written this way:



                        render-prompt () { printf "1%b2%s1%b2" 'e[0;35m' '$ ' 'e[00m'; }


                        The first argument is "1%b2%s1%b2" and this is the format. It's a good and logical place for 1 and 2, which embrace the %b parameters. (The %bs are -escaped strings and %s represents a standard string.)



                        The others are 'e[0;35m', '$ ' and 'e[00m', which correspond to %b, %s and %b in the format. Here I'd put es, as they escape the [ braces they precede.






                        share|improve this answer


























                          0












                          0








                          0







                          You correctly figured out the 1, 2 and e. But there's a better and more correct way to produce the sequences.



                          The printf command takes FORMAT as the first argument. This format consumes the subsequent arguments. So your function could be better written this way:



                          render-prompt () { printf "1%b2%s1%b2" 'e[0;35m' '$ ' 'e[00m'; }


                          The first argument is "1%b2%s1%b2" and this is the format. It's a good and logical place for 1 and 2, which embrace the %b parameters. (The %bs are -escaped strings and %s represents a standard string.)



                          The others are 'e[0;35m', '$ ' and 'e[00m', which correspond to %b, %s and %b in the format. Here I'd put es, as they escape the [ braces they precede.






                          share|improve this answer













                          You correctly figured out the 1, 2 and e. But there's a better and more correct way to produce the sequences.



                          The printf command takes FORMAT as the first argument. This format consumes the subsequent arguments. So your function could be better written this way:



                          render-prompt () { printf "1%b2%s1%b2" 'e[0;35m' '$ ' 'e[00m'; }


                          The first argument is "1%b2%s1%b2" and this is the format. It's a good and logical place for 1 and 2, which embrace the %b parameters. (The %bs are -escaped strings and %s represents a standard string.)



                          The others are 'e[0;35m', '$ ' and 'e[00m', which correspond to %b, %s and %b in the format. Here I'd put es, as they escape the [ braces they precede.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 32 mins ago









                          TomaszTomasz

                          9,94952966




                          9,94952966






















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










                              draft saved

                              draft discarded


















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













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












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
















                              Thanks for contributing an answer to Unix & Linux Stack Exchange!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f504150%2femit-zero-width-bash-prompt-sequence-from-external-binary%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Parapolítica Índice Antecedentes El escándalo Proceso judicial Consecuencias Véase...

                              How to remove border from elements in the last row?Targeting flex items on the last rowHow to vertically wrap...

                              Tecnologías entrañables Índice Antecedentes Desarrollo Tecnologías Entrañables en la...