如何在bash中为对话框命令转义空格

时间:2019-07-14 05:25:04

标签: bash dialog escaping

我试图找到一种在字符串中转义空格的方法,以便我可以将一个变量用于对话框命令(因为我有几个屏幕,并且我想为每个屏幕使用相同的设置)。问题是,如果我在字符串中插入空格,它会认为这是两个参数而不是字符串!

我尝试了所有我能想到的并且无法正常工作的事情。我试图转义空格,转义引号,单引号字符串,似乎没有任何工作。我在抓稻草。有人知道如何解决这个问题吗?

#!/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

如果我尝试运行它,它会给我"Error: Unknown option Information\Zn."而不是对话框。如果我删除"Login Information"中的空格(即改为使用“ LoginInformation”,这不是我想要的显示方式),那么它将起作用。

1 个答案:

答案 0 :(得分:0)

感谢Gordon Davisson向我指出正确的方向。我知道了我知道有人说但不发布解决方案时会感到沮丧,所以这是我的解决方案,适用于那些可能也对此感到迷those的人:

# 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
}