LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 12-22-2009, 03:15 PM   #1
DevonB
LQ Newbie
 
Registered: Dec 2009
Posts: 27

Rep: Reputation: 1
BASH - printf printing escape codes even though I have %0b defined


I have a dynamic list that I want it to print up to 250 entries in 5 grouped columns of 50; each 'group; has a number and the name of a server. I also want the number to be colored but the name column to not be colored. My code works great until I hit null characters within the array, then it starts printing escape codes. If I do not do the colorize technique, it prints blanks, just like I want it to. How can I get to behave right? The COLORIZE sourced function has the values set for $GREEN and $UNCOLOR. The list.txt has a list of servers and some other 'stuff' after the name, hence the reason for the awk.

My color code -

Code:
GREEN='\E[32;40m'
UNCOLOR='\E[00m'
The main body of code -

Code:
#!/bin/bash

. `pwd`/source/COLORIZE.func

COLORIZE

COUNTER=0
TOTAL_COUNTER=`grep . -c list.txt`

while read IGROUP_LIST
  do
    let "COUNTER += 1"
    IGROUP_NAME[$COUNTER]=`echo $IGROUP_LIST | awk '{print $1}'`
    INSTANCE_COUNTER[$COUNTER]=$COUNTER
  done < list.txt

COUNTER=0

until [ $COUNTER = "50" ]
  do
    let "COUNTER += 1"
      printf "%0b%3s%0b %15s %0b%6s%0b %15s %0b%6s%0b %15s %0b%6s%0b %15s %0b%6s%0b %15s\n" $GREEN ${INSTANCE_COUNTER[$COUNTER]} $UNCOLOR ${IGROUP_NAME[$COUNTER]} $GREEN ${INSTANCE_COUNTER[$COUNTER+50]} $UNCOLOR ${IGROUP_NAME[$COUNTER+50]} $GREEN ${INSTANCE_COUNTER[$COUNTER+100]} $UNCOLOR ${IGROUP_NAME[$COUNTER+100]} $GREEN ${INSTANCE_COUNTER[$COUNTER+150]} $UNCOLOR ${IGROUP_NAME[$COUNTER+150]} $GREEN ${INSTANCE_COUNTER[$COUNTER+200]} $UNCOLOR ${IGROUP_NAME[$COUNTER+200]}
  done

echo -e -n "\nPlease make your selection [1 - ${TOTAL_COUNTER}] : "
Once it hits the end of my list of 166 current items, it prints the literal contents of the $UNCOLOR variable instead of escaping. If I don't color at all, the list prints out only the 166 items with the right output as I expect.

Suggestions to fix it?

Devon
 
Old 12-22-2009, 03:28 PM   #2
Skaperen
Senior Member
 
Registered: May 2009
Location: center of singularity
Distribution: Xubuntu, Ubuntu, Slackware, Amazon Linux, OpenBSD, LFS (on Sparc_32 and i386)
Posts: 2,647
Blog Entries: 31

Rep: Reputation: 175Reputation: 175
Try wrapping each usage of the variable references that could be null with double quotes like:

Code:
printf "%0b%3s%0b %15s %0b%6s%0b %15s %0b%6s%0b %15s %0b%6s%0b %15s %0b%6s%0b %15s\n" $GREEN "${INSTANCE_COUNTER[$COUNTER]}" $UNCOLOR "${IGROUP_NAME[$COUNTER]}" $GREEN "${INSTANCE_COUNTER[$COUNTER+50]}" $UNCOLOR "${IGROUP_NAME[$COUNTER+50]}" $GREEN "${INSTANCE_COUNTER[$COUNTER+100]}" $UNCOLOR "${IGROUP_NAME[$COUNTER+100]}" $GREEN "${INSTANCE_COUNTER[$COUNTER+150]}" $UNCOLOR "${IGROUP_NAME[$COUNTER+150]}" $GREEN "${INSTANCE_COUNTER[$COUNTER+200]}" $UNCOLOR "${IGROUP_NAME[$COUNTER+200]}"
 
1 members found this post helpful.
Old 12-23-2009, 06:00 AM   #3
DevonB
LQ Newbie
 
Registered: Dec 2009
Posts: 27

Original Poster
Rep: Reputation: 1
That worked, thank you! Now my next question is why did that work? Why specifically after a null do escape codes stop being processed, even when specifying that they are an escape code?

Devon
 
Old 12-23-2009, 07:34 AM   #4
Skaperen
Senior Member
 
Registered: May 2009
Location: center of singularity
Distribution: Xubuntu, Ubuntu, Slackware, Amazon Linux, OpenBSD, LFS (on Sparc_32 and i386)
Posts: 2,647
Blog Entries: 31

Rep: Reputation: 175Reputation: 175
It has to do with how the shell command lines are parsed. When you have a variable in a shell script line, and that variable is an empty string, it adds nothing to that line at that point. How this behaves in the shell parsing depends on whether there are quotes or not. Without the quotes, the empty string will not even be an argument. With the quotes, it will be an argument, though it will be one with an empty string.

Type in this little script:
Code:
#!/bin/bash
echo Number of arguments is $#
Make it executable, then try it with various arguments:
Code:
altair/phil /home/phil 1> cat > littlescript
#!/bin/bash
echo Number of arguments is $#
altair/phil /home/phil 2> chmod +x littlescript
altair/phil /home/phil 3> ./littlescript abc xyz foo bar
Number of arguments is 4
altair/phil /home/phil 4> a=abc;b=xyz
altair/phil /home/phil 5> ./littlescript foo ${a} ${b} bar
Number of arguments is 4
altair/phil /home/phil 6> a="";b=""
altair/phil /home/phil 7> ./littlescript foo ${a} ${b} bar
Number of arguments is 2
altair/phil /home/phil 8> ./littlescript foo "${a}" ${b} bar
Number of arguments is 3
altair/phil /home/phil 9> ./littlescript foo "${a}" "${b}" bar
Number of arguments is 4
altair/phil /home/phil 10> ./littlescript foo "" "" bar
Number of arguments is 4
altair/phil /home/phil 11>

Last edited by Skaperen; 12-23-2009 at 07:40 AM. Reason: correct paste
 
Old 12-23-2009, 07:48 AM   #5
Skaperen
Senior Member
 
Registered: May 2009
Location: center of singularity
Distribution: Xubuntu, Ubuntu, Slackware, Amazon Linux, OpenBSD, LFS (on Sparc_32 and i386)
Posts: 2,647
Blog Entries: 31

Rep: Reputation: 175Reputation: 175
To answer your question more directly, it's not because the escape codes didn't work ... it's because the empty variables were omitted arguments (e.g. there was no argument at all there), and the arguments didn't match up with the formats because of the omissions in the middle. But where quotes are, the arguments won't be omitted even if they are an empty string. Quotes are also used coerce strings with spaces into one argument rather than letting the shell parse such strings into multiple arguments.
Code:
altair/phil /home/phil 11> c="foo bar"
altair/phil /home/phil 12> ./littlescript ${c}
Number of arguments is 2
altair/phil /home/phil 13> ./littlescript "${c}"
Number of arguments is 1
altair/phil /home/phil 14>
BTW, if there is a null character code (binary 0) in a string, that generally ends the string right before it. Any program written in C/C++ (as is the shell) without using specialized string handling will have that effect.
 
Old 12-23-2009, 01:42 PM   #6
DevonB
LQ Newbie
 
Registered: Dec 2009
Posts: 27

Original Poster
Rep: Reputation: 1
I got it, that makes sense! Because it was a null for one of the positions, it now shifts all the positions of the variables in the printf. Since every position is not a %(x)b, it prints it literal.

Thanks again!

Devon
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] printer escape codes smeezekitty Programming 6 10-13-2009 11:52 PM
How to handle ansi escape codes in C? john.daker Programming 2 11-13-2008 05:26 AM
Sending escape codes through CUPS Tracker77 Linux - Desktop 1 02-10-2008 11:45 AM
Escape Codes for Console Color trainpic Linux - General 1 03-13-2006 07:45 PM
Using escape codes to print barcodes c2tidis Linux - Software 0 09-29-2005 11:44 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 08:23 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration