0

I have a shell script that needs to trim newline from input. I am trying to trim new line like so:

    param=$1
    trimmed_param=$(echo $param | tr -d "\n")

    # is the new line in my trimmed_param?  yes
    echo $trimmed_param| od -xc

    # if i just run the tr -d on the data, it's trimmed. 
    # why is it not trimmed in the dynamic execution of echo in line 2
    echo $param| tr -d "\n" |od -xc

I run it from command line as follows:

    sh test.sh someword

And I get this output:

    0000000    6f73    656d    6f77    6472    000a
              s   o   m   e   w   o   r   d  \n
    0000011
    0000000    6f73    656d    6f77    6472
              s   o   m   e   w   o   r   d
    0000010 

The last command in the script echos what I would think trimmed_param would be if the tr -d "\n" had worked in line 2. What am I missing?

I realize I can use sed etc but ... I would love to understand why this method is failing.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
RJ Cole
  • 2,592
  • 3
  • 18
  • 23
  • 1
    Even if there *were* a literal newline appended to the parameter, command substitutions delete trailing newlines, so insofar as you only care about newlines at the *end* of input, `trimmed_param=$(echo "$param")` would have the desired effect (well, and also add a bunch of bugs depending on your shell -- `echo`'s POSIX specification is extremely loose; see the APPLICATION USAGE and RATIONALE sections of http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html, and take to heart the advice in that spec that new development use `printf` instead). – Charles Duffy Apr 25 '18 at 21:39
  • 1
    Also, `echo $foo` doesn't preserve literal newlines in `foo` -- so even if you *did* have a newline there in the first place, the string-splitting stage of shell command execution would be removing it unless you modify the line to `echo "$foo"`. – Charles Duffy Apr 25 '18 at 21:42
  • 1
    If you want to test that yourself: `three_lines=$(printf '%s\n' three separate lines)`, then compare `echo $three_lines` to `echo "$three_lines"`. There's a reason http://shellcheck.net/ warns about unquoted expansions. – Charles Duffy Apr 25 '18 at 21:44
  • @CharlesDuffy thank you. And for that link shellcheck.net. – RJ Cole Apr 25 '18 at 22:16
  • Possible duplicate of ['echo' without newline in a shell script](https://stackoverflow.com/q/11193466/608639), [How to echo out things without a newline?](https://stackoverflow.com/q/38021348/608639), [echo newline suppression](https://stackoverflow.com/q/2645174/608639), etc. – jww Apr 25 '18 at 23:08

1 Answers1

3

There has never been a newline in the param. It's the echo which appends the newline. Try

# script.sh
param=$1
printf "%s" "${param}" | od -xc

Then

bash script.sh foo

gives you

0000000    6f66    006f
          f   o   o
0000003
hek2mgl
  • 152,036
  • 28
  • 249
  • 266