1

I have printf statements that are not displaying correctly in a Terminal window. The first two display correctly but the third printf "Writing to %s$output%s" "$biwhite" "$color_off" is not showing up except for the last few characters of $output

It feels like a bug of some sort. If I substitute echo for printf the line displays correctly, minus the coloring. I've tried putting all the statements in one printf with the same results. It is as though printf reallllly hates that one sentence. I'm at a loss as to what could be causing it. I'm working in OSX.

biwhite=$(tput bold)$(tput setaf 7) #bired=$(tput bold)$(tput setaf 1) color_off=$(tput sgr0) date="$(date +%Y%m%d)" while [[ $# -gt 0 ]] ; do input="$1" #name $input as the first arugment sent to script if [ -d "$input" ] ; then #if argment is a directory, run md5deep target="${input%/}" #strip the trailing /, if any target="${target##*/}" #drop the leading directory componenets i.e. get basename output="$input"/"$target"_"$date"_checksums.md5 #set .md5 file to $output printf "%s${input##*/}%s is a directory.\n" "$biwhite" "$color_off" printf "Making checksums of all files in %s$input%s\n" "$biwhite" "$color_off" printf "Writing to %s$output%s" "$biwhite" "$color_off" md5deep -bre "$input" >> "$output" #create md5 hash (hashes) of $input and write results to $output fi shift done 

1 Answer 1

4

Generally speaking, the format string argument to printf should be constant. Thus:

printf '%s%s%s is a directory.\n' "$biwhite" "${input##*/}" "$color_off" # GOOD printf 'Writing to %s%s%s\n' "$biwhite" "$output" "$color_off" # GOOD 

...or...

printf '%s is a directory.\n' "$biwhite${input##*/}$color_off" # GOOD printf 'Writing to %s\n' "$biwhite$output$color_off" # GOOD 

As opposed to:

printf "%s${input##*/}%s is a directory.\n" "$biwhite" "$color_off" # BAD printf "Writing to %s$output%s\n" "$biwhite" "$color_off" # BAD 

Otherwise, behavior can be hard to predict:

  • Any % signs inside your "$output" can throw off how other positional arguments are interpreted.
  • Any backslash-escape sequences will be substituted with referenced characters -- a literal tab for \t, a carriage-return for \r, etc. (If you want this, use %b instead of %s in the specific positions where you want such substitutions to take place).
Sign up to request clarification or add additional context in comments.

2 Comments

Ahhh I see... $output is a file path that I want to be colorized when displayed so I thought I would need to bookend it with $biwhite and $color_off
Sure -- but by putting a %s placeholder for all three of "$biwhite", "$output" and "$color_off", or having only one placeholder and passing the full concatenated string for it, you can have that same effect without having the contents of output parsed as a format string itself.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.