Aspas corretas que escapam / preservam na função bash [duplicada]

2

O seguinte comando com 2 parâmetros faz o que eu preciso, se eu entrar em um terminal:

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

Agora, movo o texto acima para o script bash.

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'

Obviamente, isso não produzirá o mesmo resultado ou qualquer resultado útil. Mas não consigo encontrar a maneira correta de preservar e / ou escapar corretamente de citações, espaços e manter o número de parâmetros reais que mycommand vê como 2.

Eu uso o GNU bash versão 3.2.57 em um Mac.

    
por Dmitry 30.07.2018 / 23:39

2 respostas

0

Se você citar cada parâmetro, ele será tratado adequadamente como um parâmetro posicional:

#!/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, entretanto, que as cotas contendo (ou seja, mais externas) são não parte do próprio parâmetro. Vamos tentar uma invocação ligeiramente diferente da função:

$ 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 que ' s na saída em torno dos parâmetros reproduzidos são provenientes da instrução echo na função e não dos próprios parâmetros.

Para personalizar seu código de exemplo para ter mais reconhecimento de citações, podemos fazer isso:

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

Ou isto:

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

Os espaços não são permitidos (nem aceitos) na atribuição de variáveis quando não tiverem sido citados.

Em

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

Há um espaço sem aspas que divide a linha em duas palavras separadas.

Uma solução possível é:

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'

No entanto, a "melhor prática" é usar uma matriz:

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

Na execução, será impresso:

$ ./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
    
por 31.07.2018 / 01:56