Passando uma string com espaços como um argumento de function no bash

Eu estou escrevendo um script bash onde eu preciso passar uma string contendo espaços para uma function no meu script bash.

Por exemplo:

#!/bin/bash myFunction { echo $1 echo $2 echo $3 } myFunction "firstString" "second string with spaces" "thirdString" 

Quando executado, a saída esperada é:

 firstString second string with spaces thirdString 

No entanto, o que realmente é produzido é:

 firstString second string 

Existe uma maneira de passar uma string com espaços como um único argumento para uma function no bash?

você deve colocar aspas e também, sua declaração de function está errada.

 myFunction() { echo "$1" echo "$2" echo "$3" } 

E como os outros, funciona para mim também. Diga-nos qual versão do shell você está usando.

Outra solução para o problema acima é definir cada string para uma variável, chamar a function com variables ​​denotadas por um sinal de dólar literal \$ . Em seguida, na function use eval para ler a variável e a saída conforme o esperado.

 #!/usr/bin/ksh myFunction() { eval string1="$1" eval string2="$2" eval string3="$3" echo "string1 = ${string1}" echo "string2 = ${string2}" echo "string3 = ${string3}" } var1="firstString" var2="second string with spaces" var3="thirdString" myFunction "\${var1}" "\${var2}" "\${var3}" exit 0 

A saída é então:

  string1 = firstString string2 = second string with spaces string3 = thirdString 

Ao tentar resolver um problema semelhante a este, eu estava correndo para a questão do UNIX pensando que minhas variables ​​eram delimitadas por espaço. Eu estava tentando passar uma string delimitada por pipe para uma function usando o awk para definir uma série de variables ​​usadas posteriormente para criar um relatório. Eu tentei inicialmente a solução postada por ghostdog74, mas não consegui fazê-lo funcionar, pois nem todos os meus parâmetros estavam sendo passados ​​entre aspas. Depois de adicionar aspas duplas a cada parâmetro, ele começou a funcionar como esperado.

Abaixo está o estado anterior do meu código e funcionando totalmente após o estado.

Antes – Código não funcional

 #!/usr/bin/ksh #******************************************************************************* # Setup Function To Extract Each Field For The Error Report #******************************************************************************* getField(){ detailedString="$1" fieldNumber=$2 # Retrieves Column ${fieldNumber} From The Pipe Delimited ${detailedString} # And Strips Leading And Trailing Spaces echo ${detailedString} | awk -F '|' -v VAR=${fieldNumber} '{ print $VAR }' | sed 's/^[ \t]*//;s/[ \t]*$//' } while read LINE do var1="$LINE" # Below Does Not Work Since There Are Not Quotes Around The 3 iputId=$(getField "${var1}" 3) done< ${someFile} exit 0 

Depois - Código de Funcionamento

 #!/usr/bin/ksh #******************************************************************************* # Setup Function To Extract Each Field For The Report #******************************************************************************* getField(){ detailedString="$1" fieldNumber=$2 # Retrieves Column ${fieldNumber} From The Pipe Delimited ${detailedString} # And Strips Leading And Trailing Spaces echo ${detailedString} | awk -F '|' -v VAR=${fieldNumber} '{ print $VAR }' | sed 's/^[ \t]*//;s/[ \t]*$//' } while read LINE do var1="$LINE" # Below Now Works As There Are Quotes Around The 3 iputId=$(getField "${var1}" "3") done< ${someFile} exit 0 

Sua definição de myFunction está errada. Deveria ser:

 myFunction() { # same as before } 

ou:

 function myFunction { # same as before } 

Enfim, parece bem e funciona bem para mim no Bash 3.2.48.

A solução mais simples para esse problema é que você só precisa usar \" para argumentos separados por espaços ao executar um script de shell:

 #!/bin/bash myFunction() { echo $1 echo $2 echo $3 } myFunction "firstString" "\"Hello World\"" "thirdString" 

Solução simples que funcionou para mim – citado $ @

 Test(){ set -x grep "$@" /etc/hosts set +x } Test -i "3 rb" + grep -i '3 rb' /etc/hosts 

Eu pude verificar o comando grep atual (graças ao set -x).

Você poderia ter uma extensão deste problema caso seu texto inicial fosse configurado em uma variável de tipo string, por exemplo:

 function status(){ if [ $1 != "stopped" ]; then artist="ABC"; track="CDE"; album="DEF"; status_message="The current track is $track at $album by $artist"; echo $status_message; read_status $1 "$status_message"; fi } function read_status(){ if [ $1 != "playing" ]; then echo $2 fi } 

Neste caso, se você não passar a variável status_message para a frente como string (cercada por “”), ela será dividida em uma assembly de argumentos diferentes.

“$ variable” : A faixa atual é CDE no DEF by ABC

$ variável : o

Tive o mesmo tipo de problema e, de fato, o problema não era a function nem a chamada de function, mas o que eu passei como argumentos para a function.

A function foi chamada do corpo do script – o ‘main’ – então eu passei “st1 ab” “st2 cd” “st3 ef” da linha de comando e passei para a function usando myFunction $ *

O $ * causa o problema à medida que se expande em um conjunto de caracteres que serão interpretados na chamada à function usando espaços em branco como um delimitador.

A solução foi alterar a chamada para a function no tratamento explícito de argumentos do ‘principal’ para a function: a chamada seria myFunction “$ 1” “$ 2” “$ 3”, que preservará o espaço em branco dentro de cadeias de caracteres como aspas delimitarão os argumentos … Portanto, se um parâmetro puder conter espaços, ele deverá ser tratado explicitamente durante todas as chamadas de funções.

Como esta pode ser a razão para longas buscas em problemas, pode ser sábio nunca usar $ * para passar argumentos …

Espero que isso ajude alguém, algum dia, em algum lugar … Jan.