bash script with parameters with space

0

I'm doing a bash script but I have some variables that need spaces like the name, how can I make it so that a space does not take it as another parameter example

#!/bin/bash
mkdir $1
cp -a /home/x/Descargas/archivo.zip /var/www/html/
unzip /var/www/html/$1 /var/www/html/$1/
php /var/www/html/$1/install/index_cli.php --domain=$1 --db_server=$2 --db_name=$1 --prefix=$3 --db_user=$4 --db_password=$5 --email=$6 --name=$7 

The moment I run it is something like that sudo ./script.sh varlor1 value2 value4 value5 value6 value7

but that it was something like that sudo ./script.sh -value 2 -valor3 -va lor4 etc I can enter spaces and I do not take the next parameter until it separates with a - thanks

    
asked by alfredo robles cervantes 10.11.2018 в 18:33
source

2 answers

0

The IFS variables ( internal field separator ) determine the behavior of what you enter as arguments, that variable changes depending on the shell you use. If you use bash , the IFS is <espacio><tab><salto de línea> , on the other hand, if you use zsh is <espacio><tab><salto de línea><carácter nulo> .

As proof of this you can run $ echo -n "$IFS" | od -cb on your terminal and see what I'm saying.

The IFS variable is an environment variable (which you can edit for pleasure, but with care) that the shells use their characters as separators after the expansions (brace, pathname, substitution substitution, process substitution, etc.) ).

The quotes prevent 2 things: 1. Certain expansions, for example, when using "*" within a variable prevents it from expanding, 2. Prevents it from being divided according to the characters described in the IFS.

Therefore, your script should look something like this.

#!/bin/bash

db_name="$1"
db_server="$2"
prefix="$3"
db_user="$4"
db_password="$5"
email="$6"
name="$7"

mkdir "$db_name"

cp -a /home/x/Descargas/archivo.zip /var/www/html/

unzip /var/www/html/"$db_name" /var/www/html/"$db_name"/

php /var/www/html/"$db_name"/install/index_cli.php \
    --domain="$db_name" \
    --db_server="$db_server" \
    --db_name="$db_name" \
    --prefix="$prefix" \
    --db_user="$db_user" \
    --db_password="$db_password" \
    --email="$email" \
    --name="$name" 

Returning to the theme of the IFS. If you make a script like this.

#!/bin/bash

echo "Parámetro 1: $1"

And run it as follows:

$ ./ifs.sh "$(echo -e "espacio: tab\tsalto de linea\nfin")"

The result would respect the characters you entered resulting in something like this:

Parámetro 1: espacio: tab:      salto de linea:
fin

On the other hand, if you change your script to this (removing the quotation marks from the parameter susbstitution)

#!/bin/bash

echo "Parámetro 1:" $1

And you run it in the same way as the previous one, the output would look like this:

Parámetro 1: espacio: tab: salto de linea: fin

That is, it uses the characters of the IFS variable to separate blocks of text.

You can check the documentation on this effect with man 1 bash in the "QUOTING" section.

Returning to your way of raising your request, I think you had the concern that the parameters are taken into account within your program depending on a flag. And I agree a lot on that with you, only that I like it to be much more verbose to avoid confusion between the sysadmin and developers who use the program. So I suggest you apply the strategy of putting parameters with name, this I use it in the following way (I like it more than using getopts).

#!/bin/bash

# db_name="$1"
# db_server="$2"
# prefix="$3"
# db_user="$4"
# db_password="$5"
# email="$6"
# name="$7"

main() {

    while [[ $# > 0 ]]
    do
        case "$1" in

            --db_name )
                shift
                db_name="$1"
                shift
            ;;
            --db_server )
                shift
                db_server="$1"
                shift
            ;;
            --prefix )
                shift
                prefix="$1"
                shift
            ;;
            --db_user )
                shift
                db_user="$1"
                shift
            ;;
            --db_password )
                shift
                db_password="$1"
                shift
            ;;
            --email )
                shift
                email="$1"
                shift
            ;;
            --name )
                shift
                name="$1"
                shift
            ;;
            *)
                shift
            ;;
        esac
    done

    mkdir "$db_name"

    cp -a /home/x/Descargas/archivo.zip /var/www/html/

    unzip /var/www/html/"$db_name" /var/www/html/"$db_name"/

    php /var/www/html/"$db_name"/install/index_cli.php \
        --domain="$domain" \
        --db_server="$db_server" \
        --db_name="$db_name" \
        --prefix="$prefix" \
        --db_user="$db_user" \
        --db_password="$db_password" \
        --email="$email" \
        --name="$name" 

}

main "$@"

And, as long as you keep your variables in quotation marks, you will respect all the characters of the IFS.

The way to run this program (thinking of an exaggerated example) would be something like this:

$ ./ifs.sh --db_name a --db_server b --prefix c --db_user d --db_password e --email "f espacios" --name "saltos
de linea"
    
answered by 12.11.2018 / 01:09
source
1

To add arguments that include spaces, use double quotes: "va lor"

You can refer to this question for more information on arguments with spaces and special characters: link

    
answered by 11.11.2018 в 21:11