2009-12-30 16 views
107

Piszę skrypt basha, w którym muszę przekazać ciąg znaków zawierający spacje do funkcji w moim skrypcie basha.Przekazywanie ciągu znaków spacji jako argumentu funkcji w bash

Na przykład:

#!/bin/bash 

myFunction 
{ 
    echo $1 
    echo $2 
    echo $3 
} 

myFunction "firstString" "second string with spaces" "thirdString" 

Po uruchomieniu wyjście Spodziewam się: tam

firstString 
second 
string 

to sposób:

firstString 
second string with spaces 
thirdString 

Jednak to, co jest faktycznie wyjście przekazać ciąg znaków ze spacjami jako pojedynczy argument do funkcji w bashu?

+0

pracuje dla mnie ... Używam pełną składnię funkcji choć” function (bla) {echo 1 $; } ", nie można zrobić krótkiego w jedną linijkę.Nie wiesz, że to robi różnicę.Jakie wersje bash? – Eugene

+3

wypróbuj' echo "$ @" 'lub' dla i w "$ @"; wykonaj echo $ i; done' do używania poprawnie cytowanych parametrów zawierających spacje.To jest bardzo wyraźnie wspomniane we wszystkich dokumentacjach 'bash' w sekcji' pozycyjnych parametrów' – Samveen

+1

Miałem podobny problem, próbując przekazać jeden cytowany ciąg jako parametr i tylko pierwszy słowo stringa jest rozpoznawane jako część parametru Propozycja Samveena, aby zmienić 1 $ na $ @, działała dla mnie Zauważ, że przekazałem tylko jeden parametr do funkcji, ale gdybym przekazywał więcej używając instrukcji for, –

Odpowiedz

116

powinieneś umieścić cytaty, a także, Twoja deklaracja funkcji jest błędna.

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

I podobnie jak inne, działa również dla mnie. Powiedz nam, z której wersji powłoki korzystasz.

+1

Działa to bardzo dobrze także dla mnie. wywołujemy inną funkcję wewnątrz myFu nction następnie przekazuje argumenty z cytatami. Pozdrawiam :) – minhas23

+1

Czy możesz wyjaśnić, dlaczego trzeba cytatów? Próbowałem zarówno z jak i bez, i to nie działało dla mnie. Używam Ubuntu 14.04, GNU bash, wersja 4.3.11 (1) -release (x86_64-pc-linux-gnu). Co * działa * to dla mnie użycie @ @ (z cytatami lub bez). –

4

Twoja definicja funkcji myFunction jest nieprawidłowa. Powinno być:

myFunction() 
{ 
    # same as before 
} 

czyli

function myFunction 
{ 
    # same as before 
} 

W każdym razie, wygląda dobrze i działa dobrze dla mnie na Bash 3.2.48.

-2

Miał ten sam rodzaj problemu, a w rzeczywistości problemem nie była funkcja ani wywołanie funkcji, ale to, co przekazałem jako argumenty funkcji.

Funkcja została wywołana z treści skryptu - "głównego" - więc przekazałem "st1 ab" "st2 cd" "st3 ef" z wiersza poleceń i przekazałem go do funkcji za pomocą myFunction $ *

$ * powoduje problem, ponieważ rozwija się w zestaw znaków, które zostaną zinterpretowane w wywołaniu funkcji za pomocą białych znaków jako ogranicznika.

Rozwiązaniem była zmiana wywołania funkcji na jawną obsługę argumentów z "głównego" w kierunku funkcji: wywołanie byłoby wtedy funkcją myFunction "$ 1" "$ 2" "$ 3", które zachowa odstępy w ciągach jako cytaty ograniczą argumenty ... Jeśli więc parametr może zawierać spacje, powinien być obsługiwany jawnie przez wszystkie wywołania funkcji.

ponieważ może to być przyczyną długich poszukiwaniach do problemów, może być mądry, aby nigdy nie używać $ * przekazywać argumenty ...

Nadzieja pomaga to ktoś, kiedyś, gdzieś ... stycznia

+0

Poprawną odpowiedzią jest '" $ @ "', nie wszystkie cytowane '" $ 1 "', '" $ 2 "', ... parametry pozycyjne, ani '$ *'. – Samveen

0

można mieć przedłużenie tego problemu w przypadku początkowego tekstu został ustawiony w zmiennej typu string, na przykład:

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 
} 

W tym przypadku, jeśli nie przechodzą zmienną STATUS_MESSAGE naprzód jako ciąg (otoczony przez "") to będzie podzielić się szeregiem różnych argumentów.

"$ zmienna": Bieżący utwór jest CDE w DEF ABC

$ zmienna: The

+0

OP użył 'myFunction" firstString "" drugi ciąg ze spacjami "" thirdString "' i to nie działało dla niego.To, co proponujesz, nie dotyczy tego pytania. – doubleDown

14

Innym rozwiązaniem problemu powyżej jest ustawić każdy łańcuch do zmiennej, zaproszenia funkcja ze zmiennymi oznaczona literalnym znakiem dolara \$. Następnie w funkcji użyj eval, aby odczytać zmienną i wyjście zgodnie z oczekiwaniami.

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

wyjściowa wynosi zatem:

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

Próbując rozwiązać podobny problem z tym, że został uruchomiony w kwestii UNIX myśli moje zmienne przestrzeń delimeted. Próbowałem przekazać ciąg rozdzielany potokami do funkcji przy użyciu awk, aby ustawić serię zmiennych używanych później do utworzenia raportu. Początkowo wypróbowałem rozwiązanie opublikowane przez ghostdog74, ale nie mogłem go uruchomić, ponieważ nie wszystkie moje parametry były przekazywane w cudzysłowach. Po dodaniu podwójnych cudzysłowów do każdego parametru, zaczęło działać zgodnie z oczekiwaniami.

Poniżej znajduje się poprzedni stan mojego kodu iw pełni funkcjonujący po stanie.

Przed - Bez kodu Funkcjonowanie

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

Po - Funkcjonowania Kodeksu

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

proste rozwiązanie, że pracował dla mnie - cytat $ @

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

mogę zweryfikować rzeczywisty polecenie grep (dzięki set -x).

0

Najprostszym rozwiązaniem tego problemu jest to, że po prostu trzeba użyć \ „o przestrzeń oddzielona arguements gdy uruchomiony skrypt #!/bin/bash myFunction { echo $1 echo $2 echo $3 } myFunction "firstString" "\"Hello World\"" "thirdString"

Powiązane problemy