0

I was trying to enumerate a bunch of files in bash and noticed the following strange error occuring.

The input string 'rtpwatcher_Class_Sync_License_Capture' gets echo'd as 'rtpwatcher_Class_ ync_ icense_Capture', seemingly removing uppercase characters at random.

Code:

hb_names=("rtpwatcher_Truckmove_Statemachine" "rtpwatcher_Class_Sync_License_Capture")
hb_test="rtpwatcher_Truckmove_Statemachine,rtpwatcher_Class_Sync_License_Capture"

for i in $(echo $hb_test | tr ',' '\n')
do
    echo $i
done

for hb in ${hb_names[@]}; do
    echo $hb
done

Output:

rtpwatcher_Truckmove_ tatemachine
rtpwatcher_Class_ ync_ icense_Capture
rtpwatcher_Truckmove_ tatemachine
rtpwatcher_Class_ ync_ icense_Capture

I've tried changing the string to only have one upper case character (rtpwatcher_Class_sync_license_capture) and the output was 'rtpwatcher_Class_sync_license_capture' as expected.

SOLVED:

for hb in "${hb_names[@]}"; do
    echo "${hb}"
done
  • under `bash 4.4.12` this code generates the expected output (ie, no characters are removed) – markp-fuso Feb 15 '23 at 15:46
  • Cannot reproduce your issue on either `GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)` or `GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin20)`. Per @markp-fuso comment, the code generates the expected output. – j_b Feb 15 '23 at 15:49
  • On `5.2.15` this generates the expected output as well... – Jetchisel Feb 15 '23 at 15:56
  • 2
    BTW, `for i in $(anything)` is bad practice. Consider `IFS=, read -r -a hb_test_arr <<<"$hb_test"` and then `for i in "${hb_test[@]}"` if for some reason you can't just define `hb_test` as an array in the first place. – Charles Duffy Feb 15 '23 at 16:03
  • 2
    And you should be quoting `"${hb_names[@]}"` -- when you use just `${hb_names[@]}` without the quotes you're bug-for-bug compatible with `${hb_names[*]}` – Charles Duffy Feb 15 '23 at 16:03
  • 1
    And `echo "$i"`, not `echo $i` -- see [I just assigned a variable, but `echo $variable` shows something different!](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else) – Charles Duffy Feb 15 '23 at 16:04
  • 5
    Beyond that, I'd want to see an xtrace log from your script. `bash -x yourscript`, or add the line `set -x`. Likely you have a nonprintable character in your real script that got lost in the copy/paste into Stack Overflow, hence none of us being able to reproduce the problem; xtrace logs will include any such character escaped in printable form. – Charles Duffy Feb 15 '23 at 16:04
  • Have you changed the value of `IFS`? Like set it to something containing "S" and "L"? – Gordon Davisson Feb 15 '23 at 19:01
  • Thanks Charles Duffy that indeed fixed it, seems like bash interprets the output if the quotes are missing. How can I mark your answer? – SATANS'418 Feb 16 '23 at 08:58
  • @SATANS'418 Which suggestion fixed it, quoting variables or looking for nonprinting characters or something else? Also, if it was a quoting problem, you should *also* check `IFS`, since a nonstandard value for that is a problem waiting to happen. – Gordon Davisson Feb 18 '23 at 16:56
  • @GordonDavisson, given that quotes resolved the issue, what was happening there? I could see a custom IFS stripping one of "S" or "L" but not both! Seems more like a set stripping using sed. No problems with OP's original script using my version of bash (GNU bash, version 5.0.17(1)-release x86_64-pc-linux-gnu). – Eric Marceau Feb 19 '23 at 23:29
  • @EricMarceau If `IFS` is set to something containing *both* "S" and "L", it'll treat both as whitespace. Try `(hb_test="rtpwatcher_Truckmove_Statemachine,rtpwatcher_Class_Sync_License_Capture"; IFS="SL"; echo $hb_test | tr ',' '\n')` to see the effect (the parentheses are there to keep the weird `IFS` value from messing up your shell). – Gordon Davisson Feb 20 '23 at 01:08
  • I was under the impression that **IFS** was a character/string considered as a **single** pattern for splitting. I did not think that it was considered a **set** of distinct patterns, each one for splitting !!! Is that what you are suggesting, given the behaviour for each of S and L ? – Eric Marceau Feb 20 '23 at 01:18
  • @EricMarceau `IFS` is treated as a set of whitespace characters, not a single pattern. According to [the POSIX standard](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05), "The shell shall treat *each character of* the `IFS` as a delimiter" (emphasis added). Also, the default value of `IFS` consists of a space, a tab, and a newline (i.e. `IFS=$' \t\n'`), and you don't need that entire sequence in a string for it to be split as whitespace. – Gordon Davisson Feb 20 '23 at 02:12
  • @GordonDavisson, thank you! You learn every day! – Eric Marceau Feb 20 '23 at 02:17

0 Answers0