Passare una stringa con spazi come argomento di funzione in bash

Sto scrivendo uno script bash in cui ho bisogno di passare una stringa contenente spazi a una funzione nel mio script bash.

Per esempio:

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

Quando viene eseguito, l’output che mi aspetto è:

 firstString second string with spaces thirdString 

Tuttavia, ciò che viene effettivamente prodotto è:

 firstString second string 

C’è un modo per passare una stringa con spazi come singolo argomento a una funzione in bash?

dovresti mettere le virgolette e anche la tua dichiarazione di funzione è sbagliata.

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

E come gli altri, funziona anche per me. Dicci quale versione della shell stai usando.

Un’altra soluzione al problema precedente è impostare ogni stringa su una variabile, chiamare la funzione con le variabili denotate da un simbolo del dollaro letterale \$ . Quindi nella funzione utilizzare eval per leggere la variabile e produrre come previsto.

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

L’output è quindi:

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

Nel tentativo di risolvere un problema simile a questo, mi sono imbattuto nel problema di UNIX pensando che le mie variabili fossero delimitate nello spazio. Stavo cercando di passare una stringa delimitata da una pipe a una funzione usando awk per impostare una serie di variabili utilizzate in seguito per creare un report. Inizialmente ho provato la soluzione postata da ghostdog74 ma non riuscivo a farla funzionare in quanto non tutti i miei parametri venivano passati tra virgolette. Dopo aver aggiunto virgolette a ciascun parametro, ha iniziato a funzionare come previsto.

Di seguito è riportato lo stato precedente del mio codice e completamente funzionante dopo lo stato.

Prima – Codice non funzionante

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

After - Codice di funzionamento

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

La tua definizione di myFunction è errata. Dovrebbe essere:

 myFunction() { # same as before } 

o:

 function myFunction { # same as before } 

Ad ogni modo, sembra a posto e funziona perfettamente con Bash 3.2.48.

La soluzione più semplice a questo problema è che devi usare \" per argomenti separati da spazio quando esegui uno script di shell:

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

Soluzione semplice che ha funzionato per me – quotata $ @

 Test(){ set -x grep "[email protected]" /etc/hosts set +x } Test -i "3 rb" + grep -i '3 rb' /etc/hosts 

Potrei verificare il comando grep (grazie a set -x).

Si potrebbe avere un’estensione di questo problema nel caso in cui il testo iniziale sia stato impostato in una variabile di tipo stringa, ad esempio:

 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 } 

In questo caso se non si passa la variabile status_message in avanti come stringa (circondata da “”) verrà suddivisa in un mount di argomenti diversi.

“$ variabile” : la traccia corrente è CDE a DEF di ABC

$ variabile : The

Aveva lo stesso tipo di problema e in effetti il ​​problema non era la funzione né la funzione chiamata, ma ciò che passavo come argomenti alla funzione.

La funzione è stata chiamata dal corpo dello script – il ‘main’ – così ho passato “st1 ab” “st2 cd” “st3 ef” dalla riga di comando e passato alla funzione usando myFunction $ *

$ * Causa il problema mentre si espande in un set di caratteri che saranno interpretati nella chiamata alla funzione usando spazi bianchi come delimitatore.

La soluzione era di cambiare la chiamata alla funzione nella gestione esplicita degli argomenti dal ‘principale’ verso la funzione: la chiamata sarebbe quindi myFunction “$ 1” “$ 2” “$ 3” che preserverà gli spazi bianchi all’interno delle stringhe come le virgolette delimiteranno gli argomenti … Quindi se un parametro può contenere spazi, dovrebbe essere gestito esplicitamente in tutte le chiamate di funzioni.

Poiché questo potrebbe essere il motivo per lunghe ricerche di problemi, potrebbe essere saggio non usare mai $ * per passare argomenti …

Spero che questo aiuti qualcuno, un giorno, da qualche parte … Jan.