1

I'm trying to figure a way to escape spaces in a string so I can put together a variable to use for the dialog command (since I have a few screens and I want to use the same setup for each screen). Thing is, if I put a string with spaces in, it thinks it's two parameters and not a string!

I tried everything I could think of and can't get it to work. I've tried escaping the space, escaping quotes, single quoting the string, nothing seems to work. I'm grasping straws. Anyone know how to fix this?

#!/bin/bash

DIALOG=${DIALOG=dialog --colors --title "\Z0Login Information\Zn"}

$DIALOG --ok-label "Submit" \ 
        --backtitle "My Configuration" \
        --insecure "$@" \
        --colors --mixedform "Enter the login information:\n\n\Z1Use arrow keys and TAB to navigate.\nPress ENTER to cancel.\Zn\n" \
22 100 0 \
          "   Your Username:"  1 1 ""  1 27 150 0 0 \
          "   Your Password:"  3 1 ""  3 27 150 0 1 \
          " Verify Password:"  4 1 ""  4 27 150 0 1

It gives me "Error: Unknown option Information\Zn." instead of a dialog box if I try to run it. If I remove the space in "Login Information" (ie. use "LoginInformation" instead, which is not how I want to present it), it works.

Manak
  • 261
  • 3
  • 13
  • 1
    Please take a look: http://www.shellcheck.net/ – Cyrus Jul 14 '19 at 05:52
  • 2
    Use an array instead of a plain variable. Do *NOT* use `eval. See [BashFAQ #50](http://mywiki.wooledge.org/BashFAQ/050) and [Why does shell ignore quotes in arguments passed to it through variables?](https://stackoverflow.com/questions/12136948/why-does-shell-ignore-quotes-in-arguments-passed-to-it-through-variables) – Gordon Davisson Jul 14 '19 at 06:29
  • @Cyrus. Thanks, but I put it in there and it was fine. No issues. Yet it still doesn't work (same error when I run it at the command prompt). –  Jul 14 '19 at 14:52
  • @Gordon Davisson: Thank you! You pointed me in the right direction. I'll be posting my answer in a moment. Unfortunately I don't have enough "reputation" points to upvote your comment or I would! –  Jul 14 '19 at 22:10

1 Answers1

1

Thank you to Gordon Davisson for pointing me in the right direction. I got it working. I know how frustrating it is when someone says that but don't post a solution so here is my solution for those who also may have stumbled with this:

# Login Dialog Box with Password Verification Example
# By Tika Carr
# July 15, 2019
#
# *****************************************************************************
#                                GPL 3 License
#     This program is free software: you can redistribute it and/or modify
#     it under the terms of the GNU General Public License as published by
#     the Free Software Foundation, either version 3 of the License, or
#     (at your option) any later version.
#
#     This program is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#     GNU General Public License for more details.
#
#     You should have received a copy of the GNU General Public License
#     along with this program.  If not, see <https://www.gnu.org/licenses/>.
# *****************************************************************************
#
# NOTE: While this script should work as-is (you do need to install the 'dialog'
# package first), you should adjust this code to suit your needs.
#
# Example Usage:
#
# #!/bin/bash
#
# . ./dialog.inc
#
# declare -a MYDLG=("FTP Login"
# "FTP Setup"
# "Enter the login information:\nIf you make a mistake, you can do it over."
# "           Host: "
# "       Username: "
# "       Password: *"
# )
#
# multiDlg "${MYDLG[@]}"
# RESULT=$?
# if [[ $RESULT != 255 ]]; then
#     # Success
#     read -r FTPHOST FTPUSER FTPPWD <<<$(echo "${MD_RESULT[0]}" "${MD_RESULT[1]}" "${MD_RESULT[2]}")
#     echo "FTP Host: $FTPHOST"
#     echo "FTP User: $FTPUSER"
#     echo "FTP Password: Validated OK."
#     unset MD_RESULT
# fi
# ************************************************

multiDlg() {
    PARAMS=("$@")
DLG=('--colors'
'--title "\Z0'${PARAMS[0]}'\Zn"'
'--ok-label "Submit"'
'--backtitle "'${PARAMS[1]}'"'
'--insecure "$@"'
'--colors'
'--mixedform "'${PARAMS[2]}'\n\n\Z1Use arrow keys and TAB to navigate.\nPress ENTER to cancel.\Zn\n "'
)
    # Construct Dialog Box
    LNS=()
    count=0
    OFFSET=$(( 11 + $( echo -e "${PARAMS[2]}" | wc -l ) ))

    for (( i = 3; i < ${#PARAMS[@]}; (( i++ )) )) do
        IDX=$count
        (( count++ ))
        ITM="${PARAMS[i]}"
        FLG="${ITM:${#ITM} -1:1}"
        if [ "$FLG" == "*" ]; then
            ITM="${ITM::-1}"
            if [[ ${#PARAMS[@]} > 4 ]]; then (( count++ )); fi
            LNS[i]="\"$ITM\" $count 1 \"\" $count 27 150 0 1"
            (( count++ ))
            LNS[i + 1]="\"Verify Password: \" $count 1 \"\" $count 27 150 0 1"
        else
            LNS[i]="\"$ITM\" $count 1 \"\" $count 27 150 0 0"
        fi

    done
    # This is to calculate the # of lines total needed, considering that the
    # above instructions are also in the dialog box.
    count=$(( $count + $OFFSET ))
    LNS[0]="$count 100 0"
    CMD="dialog ${DLG[@]} ${LNS[@]}"

    # Show Dialog Box
    exec 3>&1
    VALS=$(bash -c "${CMD}" 2>&1 1>&3)
    exec 3>&-
    IFS=$'\n' read -d '' -ra MD_RESULT < <(printf '%s\0' "$VALS")

    # Field Check
    for (( i = 2; i < ${#MD_RESULT[@]} - 1; i++ )); do
        if [[ "${MD_RESULT[i]}" == "" ]]; then
            return $DLG_NULL
        fi
    done

    # Password Check
    if [ "$FLG" == "*" ]; then
        if [ "${MD_RESULT[IDX]}" != "${MD_RESULT[IDX + 1]}" ]; then
            unset MD_RESULT
            dialog --title "Input Error" --msgbox 'You made an error in one of the input fields.\n\nTry again.' 8 30
            # Clear Screen
            echo -e '\033c';
            multiDlg "${PARAMS[@]}"
        else
            # Remove the extra password
            # Clear Screen
            echo -e '\033c';
            if [[ ${#MD_RESULT[@]} != 0 ]]; then
                unset 'MD_RESULT[${#MD_RESULT[@]}-1]'
            fi
        fi
    fi

    if [[ ${#MD_RESULT[@]} == 0 ]]; then return 255; fi
}