0

I am using the following bash function to print a multiline strings in colour.

  desc="
 Syp:
 {-W,-w,--wht}
 -f FILE
   Print Syp brief
 Red:
   Some red details here.
 Code:
   Some code here
   More code
 Red:
   Some red details here.
 Blu:
   Some blue details here.
   Some blue details here.

 Mgn:
   Magonta

 Cyn:
   Some details here.

 Code:
   Code here
   More code

 Rst:
   Wore"

fire "$desc"

Things work as expected when using Wht:, Grn:, Blu:, Ylw:, Red:, Amb:, Cyn:, Mgn: but not when using Syp: and Code:. I have difficulty understanding how they would behave differently.

Syp: and Code: are getting called by !kl.

fire ()
 {
  awk 'BEGIN { kl=0
         ("tput sgr0") |& getline rst
         ka = "Wht 15 Grn 34 Blu 39 Ylw 11 Red 196 Amb 214"
         kb = "Cyn 51 Mgn 201 Syp 196 Code 196"
         ks = sprintf("%s %s", ka, kb)
         n = split(ks, kaggr)
         for ( i=1; i<n; i+=2 ) {
           knam = kaggr[i] ":"
           knum = kaggr[i+1]
           ("tput bold; tput setaf " knum) |& getline tseq[knam]
          }
       }

       ($1 in tseq) { kl=1 ; ctp=$1 ; next }
       /Rst:/ { kl=0 ; next }

       kl { printf("%s%s%s\n", tseq[ctp], $0, rst) }
       !kl { printf("%s\n", $0) }
      ' <<< "$@"
 }
11
  • ("tput sgr0") |& getline rst, etc. - you're still using a coprocess unnecessarily, not closing it when done, and not checking for getline failure as I showed and discussed in my previous answer](unix.stackexchange.com/a/735256/133219). Also, ks = sprintf("%s %s", ka, kb) = ks = ka " " kb, no need to complicate it. You don't need to do that, though, you could just use a backsalash at the end of the first line to define a string across 2 lines if you prefer that over defining a single long string. Commented Feb 13, 2023 at 12:28
  • Syp: and Code: would not behave differently from any of the other strings. Maybe your getline is failing, idk. Or maybe you have some control char at the end of those input lines. You didn't say in your question in what way Syp: and Code: don't work as expected (wrong output? no output? error messages? something else?) - please add that info to your question. Commented Feb 13, 2023 at 12:31
  • Syp: and Code: are getting called by !kl. There should not be any getline failure for "tput sgr0". Commented Feb 13, 2023 at 12:37
  • "there should not be any failure" doesn't mean there won't be any failure. That's why we write code to test for things that can fail, not because we expect them to fail but because we don't expect them to but have to be able to handle it when they do. getline can fail so just write your code to handle it if/when it does - I already showed you how to do that, its just a few more characters. Commented Feb 13, 2023 at 12:39
  • After kl is set to 1 in your code, it cannot be reset to 0 until Rst: is seen in your input so it's impossible for kl to be 1 for the key strings above Code: and then somehow get set to 0 again (making !kl true) when Code: is present, even if you did have control chars in your input so that rules that out. Commented Feb 13, 2023 at 12:44

1 Answer 1

0

You're spawning a coprocess the first time you call tput for the color code 196 (for Red) and not closing the pipe to it so somethings getting hung up the next 2 times you try to use that same pipe to that same process (for Syp and Code). As I've mentioned a couple of times now:

  1. don't use coprocesses for this as you don't need to,
  2. do test for getline failing (had you done that your code would have reported this problem to you), and
  3. do close the pipes you open as you go.

Also - you don't need to use 3 separate variables for this:

     ka = "Wht 15 Grn 34 Blu 39 Ylw 11 Red 196 Amb 214"
     kb = "Cyn 51 Mgn 201 Syp 196 Code 196"
     ks = sprintf("%s %s", ka, kb)

you could just do:

     ks = "Wht 15 Grn 34 Blu 39 Ylw 11 Red 196 Amb 214 " \
          "Cyn 51 Mgn 201 Syp 196 Code 196"

Also, this:

   kl { printf("%s%s%s\n", tseq[ctp], $0, rst) }
   !kl { printf("%s\n", $0) }

is just:

   kl { print tseq[ctp] $0 rst }
   !kl { print }

you're complicating your code unnecessarily with all those [s]printfs.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.