2

This question already has an answer here:

The following command with 2 parameters does what I need if I enter it in a terminal:

mycommand 'string that includes many spaces and double quotes' 'another string that includes many spaces and double quotes'

Now I move the above to the bash script.

C=mycommand 'string that includes many spaces and double quotes'
function f {
 $C $1
}
# let's call it
f 'another string that includes many spaces and double quotes'

Obviously this is not going to produce the same result, or any useful result. But I can not come up with the correct way of preserving and/or properly escaping quotes, spaces and keeping number of actual parameters that mycommand sees as 2.

I use GNU bash version 3.2.57 on a Mac.

marked as duplicate by Kusalananda bash Jul 31 '18 at 16:30

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

0

If you quote each parameter, it will be properly handled as a positional parameter:

#!/usr/local/bin/bash
f() {
  echo "function was called with $# parameters:"
  while ! [[ -z $1 ]]; do
    echo "  '$1'"
    shift
  done
}
f "param 1" "param 2" "a third parameter"
$ ./459461.sh
function was called with 3 parameters:
  'param 1'
  'param 2'
  'a third parameter'

Note however that the containing (i. e. outermost) quotes are not part of the parameter itself. Let's try a slightly different invocation of the function:

$ tail -n1 459461.sh
f "them's fightin' words" '"Holy moly," I shouted.'
$ ./459461.sh
function was called with 2 parameters:
  'them's fightin' words'
  '"Holy moly," I shouted.'

Observe that the 's in the output surrounding the reproduced parameters are coming from the echo statement in the function, and not the parameters themselves.

To dress up your example code to be more quote-aware, we can do this:

C=mycommand
f() {
  $C "unchanging first parameter" "$1"
}
# let's call it
f 'another string that includes many spaces and double quotes'

Or this:

C=mycommand
f() {
  $C "$1" "$2"
}
# let's call it
f 'Some string with "quotes" that are scary' 'some other "long" string'
0

Spaces are not allowed (nor accepted) in variable assignment when unquoted.

In

C=mycommand 'string that includes many spaces and double quotes'

There is an unquoted space that breaks the line in two separate words.

One possible solution is:

CMD=mycommand
s1='string that includes many "spaces" and "double" quotes'
function f {
    "$CMD" "$s1" "$1"
}
# let's call it
f 'another string that includes many "spaces" and "double" quotes'

However, the "best practice" is to use an array:

#!/bin/bash
# Define the functions to use:
mycommand(){ echo "Number of arguments: $#"
             echo "Full command called:"
             echo "mycommand" "$@"
           }
f (){
        "${cmd[@]}" "$1"
    }

# Define the command to be executed:
cmd=( mycommand 'string that includes many "spaces" and "double" quotes' )

# let's call it:
f 'another string that includes many "spaces" and "double" quotes'

On execution it will print:

$ ./script
Number of arguments: 2
Full command called:
mycommand string that includes many "spaces" and "double" quotes another string that includes many "spaces" and "double" quotes
  • Spaces absolutely are allowed, you just have to ensure that they don't get parsed in the wrong order. This is what quotes are for. – DopeGhoti Jul 31 '18 at 15:19
  • In C=mycommand 'string that includes many spaces and double quotes' there is an unquoted space. That is the problem. @DopeGhoti – Isaac Jul 31 '18 at 15:21
  • So.. quote or escape it? – DopeGhoti Jul 31 '18 at 15:56
  • Yes, that may be possible. But the following string contains "double quotes" which will complicate this kind of solution. In any case, the OP should be told of this problem which you didn't in your answer. @DopeGhoti – Isaac Jul 31 '18 at 16:00
  • A string enclosed in strong quotes can freely contain any number of spaces or double-quotes; a string enclosed in weak or weak quotes can contain any number of spaces or single-quotes. It's only when your string itself contains both single- and double-quotes that you have to get creative; which is not mentioned as the use-case in the OP. – DopeGhoti Jul 31 '18 at 16:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.