Search code examples
bashshellshubuntu-12.04lowercase

Converting read variables to lowercase in sh on ubuntu


I have the following situation:

#!/bin/bash

echo "Please enter a word:"
read foobar

The script is getting called with sh script.sh in the Ubuntu terminal.
Searching on the internet for solutions I found:

foobar=${foobar,,}
echo $foobar

The above approach does only work with bash script.sh
So I went on researching and found:

echo $foobar | tr '[:upper:]' '[:lower:]'

Which does indeed work for both, bash and sh, but without the echo it does not work.
It also prints the read input two times instead of one like so:
Y
y

So how can I do this for sh without printing the read input twice?


Solution

  • It's probably because you didn't assign the translated output to a variable yet. Also I suggest quoting your variables around doublequotes to prevent word splitting and pathname expansion.

    foobar=$(echo "$foobar" | tr '[:upper:]' '[:lower:]')
    

    If you're using case and you just need to check if an input is y or Y either way you can use a glob pattern like this. There's no need to transliterate it to lowercase form.

    case $foobar in
    [yY])
        echo "User said yes."
        ;;
    *)
        echo "User said no."
        ;;
    esac
    

    Also you can somehow suppress showing user input by using -s:

    read -s foobar
    

    As a whole to make your code work well in both bash and sh you should already remove the part which is bash specific:

    #!/bin/bash
    echo "Please enter a word:"
    read -s foobar
    foobar=$(echo "$foobar" | tr '[:upper:]' '[:lower:]')
    echo "$foobar"
    

    And if it's just about showing the smaller form, you can skip the assignment. But don't use another echo along with it:

    #!/bin/bash
    echo "Please enter a word:"
    read -s foobar
    echo "$foobar" | tr '[:upper:]' '[:lower:]'
    

    Another alternative form from case. This is meant to be POSIX compatible.

    if [ "$foobar" = y ] || [ "$foobar" = Y ]; then
        echo "User said yes."
    else
        echo "User said no."
    fi
    

    In bash it could be simply like this. It would work even in earlier versions that doesn't support ${parameter,,} feature.

    if [[ $foobar == [yY] ]]; then
        echo "User said yes."
    else
        echo "User said no."
    fi