0

I'm trying to create a variable in a bash script and the first space is causing issues.

The variable looks something like this:

VAR="
   --option1=foo \
   --option2=bar \
   --option3='something here with spaces'"

I'm trying to run a "make install" and it always complains about the first space (ie. before the word "here" in the above example).

How do I create a variable with spaces? I tried using double-quotes, various attempts at escaping the single-quotes, and I can't get anything to work.

What am I doing wrong?

Actual code below:

            NGINX_OPTIONS="
            --prefix=/etc/nginx \
            --sbin-path=/usr/sbin/nginx \
            --conf-path=/etc/nginx/nginx.conf \
            --error-log-path=/var/log/nginx/error.log \
            --http-log-path=/var/log/nginx/access.log \
            --pid-path=/var/run/nginx.pid \
            --lock-path=/var/run/nginx.lock \
            --http-client-body-temp-path=/var/cache/nginx/client_temp \
            --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
            --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
            --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
            --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
            --user=nginx \
            --group=nginx \
            --with-ld-opt='-ljemalloc -Wl,-z,relro -Wl,-rpath,/usr/local/lib -Wl,--as-needed -pie' \
            --with-cc-opt='-m64 -march=native -DTCP_FASTOPEN=23 -g -O3 -Wno-error=strict-aliasing -fstack-protector-strong -flto -fuse-ld=gold --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wno-deprecated-declarations -gsplit-dwarf'"

            NGINX_MODULES="
            --with-compat \
            --with-threads \
            --with-file-aio \
            --with-http_addition_module \
            --with-http_auth_request_module \
            --with-http_ssl_module \
            --with-http_v2_module \
            --with-http_mp4_module \
            --with-http_slice_module \
            --with-http_stub_status_module \
            --with-http_realip_module \
            --with-http_secure_link_module \
            --with-http_slice_module \
            --with-http_sub_module \
            --with-mail \
            --with-mail_ssl_module \
            --with-stream \
            --with-stream_realip_module \
            --with-stream_ssl_module \
            --with-stream_ssl_preread_module"

            ./configure $NGINX_OPTIONS $NGINX_MODULES
            make
            make install
Dario Zadro
  • 1,143
  • 2
  • 13
  • 23
  • Escape the spaces with a backslash. Something like this: ```--option3='something\ here\ with\ spaces'``` – accdias May 02 '19 at 06:45
  • Doesn't work. Says ./configure: error: invalid option "here\" (I'm replacing the word here as the 2nd parameter after the first space) – Dario Zadro May 02 '19 at 06:52
  • Escape the quotes with a backslash then: ```--option3=\'something here with spaces\'``` – accdias May 02 '19 at 06:56
  • Already tried that before posting. – Dario Zadro May 02 '19 at 06:56
  • 1
    Show the code that *uses* this variable? – Shawn May 02 '19 at 06:57
  • Putting quotes, backslashes, etc in variables' values doesn't do anything useful (except in weird situations). See: [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 May 02 '19 at 07:04
  • 1
    Can it be something with the `Makfile`? Try copying it into a shellscript en replace `/configure $NGINX_OPTIONS $NGINX_MODULES` with `echo $NGINX_OPTIONS $NGINX_MODULES` – Walter A May 02 '19 at 10:33

2 Answers2

3

You haven't shown how you're using this variable, but if I understand correctly, you have a command that includes $VAR outside of quotation marks.

The problem is that this:

echo $VAR

is equivalent to this:

echo "--option1=foo" "--option2=bar" "--option3='something" "here" "with" "spaces'"

because whitespace inside the variable is significant, but quotation-marks inside the variable are not.

Instead, you need to use an array. You can declare the variable like this:

VAR=(
   --option1=foo
   --option2=bar
   --option3='something here with spaces'
)

and use it like this:

echo "${VAR[@]}"       # note the quotation-marks

which is equivalent to this:

echo "--option1=foo" "--option2=bar" "--option3=something here with spaces"
ruakh
  • 175,680
  • 26
  • 273
  • 307
  • I've added my actual code. Not sure how to apply with my code. – Dario Zadro May 02 '19 at 07:05
  • I need the var to equal `--option1=foo --option2=bar --option3='something here'` – Dario Zadro May 02 '19 at 07:24
  • @DarioZadro: I'm pretty sure that you're mistaken; that is probably *not* what you actually need. The only reason that you would want something like that is if you're inserting the variable into a command that will then get *re*-parsed (e.g. by `eval`, or by a separate call to Bash). And from what you've posted, that does *not* seem to be the case. – ruakh May 02 '19 at 20:38
0

I tried every possible combination of escaping quotes and finally ended up with a "configure" statement without having a double-quoted or single-quoted variable like this:

    ./configure --prefix=/etc/nginx \
                --sbin-path=/usr/sbin/nginx \
                --conf-path=/etc/nginx/nginx.conf \
                --error-log-path=/var/log/nginx/error.log \
                --http-log-path=/var/log/nginx/access.log \
                --pid-path=/var/run/nginx.pid \
                --lock-path=/var/run/nginx.lock \
                --http-client-body-temp-path=/var/cache/nginx/client_temp \
                --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
                --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
                --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
                --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
                --user=nginx \
        --group=nginx \
        --with-cc-opt="-m64 -march=native -DTCP_FASTOPEN=23 -g -O3 -Wno-error=strict-aliasing -fstack-protector-strong -flto -fuse-ld=gold --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wno-deprecated-declarations -gsplit-dwarf" \
        --with-ld-opt="-ljemalloc -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie" \
        $NGINX_MODULES

I also had some errors like having to install "jemalloc" using:

apt-get install libjemalloc-dev

This was a larger exercise in building nginx from source than it was spaces or quotes in the bash script. I hope this helps someone else with the many challenges I've encountered.

Dario Zadro
  • 1,143
  • 2
  • 13
  • 23