Pasar una cadena con espacios como un argumento de función en bash

Estoy escribiendo un script bash donde necesito pasar una cadena que contiene espacios para una función en mi script bash.

Por ejemplo:

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

Cuando se ejecuta, la salida que esperaría es:

 firstString second string with spaces thirdString 

Sin embargo, lo que en realidad es producto es:

 firstString second string 

¿Hay alguna manera de pasar una cadena con espacios como un único argumento a una función en bash?

deberías poner comillas y también, tu statement de función es incorrecta.

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

Y como los demás, también funciona para mí. Cuéntanos qué versión de shell estás usando.

Otra solución al problema anterior es establecer cada cadena a una variable, llamar a la función con variables denotadas por un signo de dólar literal \$ . Luego, en la función use eval para leer la variable y la salida como se esperaba.

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

La salida es entonces:

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

Al tratar de resolver un problema similar a este, me encontré con el problema de UNIX pensando que mis variables estaban delimitadas en el espacio. Estaba tratando de pasar una cadena delimitada por tuberías a una función usando awk para establecer una serie de variables que luego se usaron para crear un informe. Inicialmente probé la solución publicada por ghostdog74 pero no pude hacerlo funcionar ya que no todos mis parámetros se pasaban entre comillas. Después de agregar comillas dobles a cada parámetro, comenzó a funcionar como se esperaba.

Debajo está el estado anterior de mi código y completamente funcional después del estado.

Antes – Código no 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 

Después - Código de funcionamiento

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

Tu definición de myFunction es incorrecta. Debería ser:

 myFunction() { # same as before } 

o:

 function myFunction { # same as before } 

De todos modos, se ve bien y funciona bien para mí en Bash 3.2.48.

La solución más simple para este problema es que solo necesita usar \" para argumentos separados por espacios cuando se ejecuta un script de shell:

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

Solución simple que funcionó para mí, citada $ @

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

Pude verificar el comando grep real (gracias a set -x).

Puede tener una extensión de este problema en caso de que su texto inicial se haya establecido en una variable de tipo de cadena, por ejemplo:

 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 } 

En este caso, si no pasa la variable status_message hacia delante como una cadena (rodeada por “”), se dividirá en una serie de diferentes argumentos.

“$ variable” : la pista actual es CDE en DEF por ABC

$ variable : El

Tenía el mismo tipo de problema y, de hecho, el problema no era la función ni la función llamada, sino lo que pasé como argumentos para la función.

La función fue llamada desde el cuerpo del script, el ‘main’, así que pasé “st1 ab” “st2 cd” “st3 ef” desde la línea de comando y se lo pasé a la función usando myFunction $ *

El $ * causa el problema a medida que se expande en un conjunto de caracteres que se interpretarán en la llamada a la función usando espacios en blanco como un delimitador.

La solución fue cambiar la llamada a la función en el manejo explícito de argumentos del ‘main’ hacia la función: la llamada sería myFunction “$ 1” “$ 2” “$ 3” que conservará el espacio en blanco dentro de cadenas a medida que las citas delimiten los argumentos … Entonces, si un parámetro puede contener espacios, debe manejarse de manera explícita a lo largo de todas las llamadas de funciones.

Como esta puede ser la razón de largas búsquedas de problemas, puede ser sabio nunca usar $ * para pasar argumentos …

Espero que esto ayude a alguien, algún día, en algún lugar … Jan.