stringbashunixechobash4

Echoing an echo argument in Bash


Here is the code that shows the problem:

#!/bin/bash

function char() {
    local char="$(echo $1 | cut -c2)"    # Gets second character from argument.
    echo $char
}

char -a                                  # Outputs 'a'.
char -e                                  # Or 'char -n' outputs nothing.

I want this code to output [ 'a', 'e' ] instead of [ 'a', nothing ].

I think that the problem is in echo $1. My question is kind of similar to this one. But it seems that most solutions don't work for me. I think that Bash changed it's behavior from version in that question: '3.00.15(1)-release (x86_64-redhat-linux-gnu)'.

My Bash version is '4.3.30(1)-release (i586-pc-linux-gnu)'. I have tried:

echo x-e                                 # Outputs 'x-e'.
echo -- -e                               # Outputs '-- -e'.
echo "-e "                               # Outputs '-e'.

Only little "hack" that works is echo "$1 ". But I've got the feeling that it's not the best thing to do.

P.S. I personally find this pretty interesting. Thanks for any thoughts on this.


Solution

  • -e is a flag some versions of echo interpret. The solution here is don't use echo, instead use printf:

    printf '%s' "$1" | cut -c2
    

    From help echo in bash:

    Options:
     -n        do not append a newline
     -e        enable interpretation of the following backslash escapes
     -E        explicitly suppress interpretation of backslash escapes
    

    so when the variable expands and you try to run echo -e it's not going to echo the string -e it's telling echo to make backslashes mean the escape sequence.

    For a thorough discussion of Why printf is better than echo read the excellent answers there.

    If you're trying to process command line options here, you might consider other approaches though. Like getopts or reading here about some great options