Piszę skrypt bash, w którym muszę przekazać ciąg zawierający spacje do funkcji w moim skrypcie bash.
Na przykład:
#!/bin/bash
myFunction
{
echo $1
echo $2
echo $3
}
myFunction "firstString" "second string with spaces" "thirdString"
Po uruchomieniu oczekiwany wynik to:
firstString
second string with spaces
thirdString
Jednak w rzeczywistości otrzymujemy:
firstString
second
string
Czy istnieje sposób na przekazanie ciągu znaków ze spacjami jako pojedynczego argumentu do funkcji w bash?
echo "$@"
lubfor i in "$@"; do echo $i ; done
użyj poprawnie cytowanych parametrów zawierających spacje. Jest to bardzo wyraźnie wymienione w całejbash
dokumentacji wpositional parameters
sekcji.myFunction "$@"
Odpowiedzi:
powinieneś umieścić cudzysłowy, a także deklaracja funkcji jest nieprawidłowa.
I tak jak inne, działa również na mnie. Powiedz nam, jakiej wersji powłoki używasz.
źródło
$@
zachowuje się jak bez cudzysłowu$*
- wyniki są dzielone na ciągi, a następnie indywidualnie rozwijane globalnie, więc jeśli masz tabulatory, zostaną one zamienione na spacje, jeśli masz słowa, które można obliczyć jako wyrażenia glob, będzie itp.Innym rozwiązaniem powyższego problemu jest ustawienie każdego ciągu na zmienną, wywołanie funkcji ze zmiennymi oznaczonymi literowym znakiem dolara
\$
. Następnie w funkcji użyj,eval
aby odczytać zmienną i wyprowadzić zgodnie z oczekiwaniami.Wynik jest zatem:
Próbując rozwiązać problem podobny do tego, natknąłem się na problem UNIX, myśląc, że moje zmienne są rozdzielane spacjami. Próbowałem przekazać ciąg znaków rozdzielonych potokami do funkcji używającej
awk
do ustawienia serii zmiennych, które później zostały użyte 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łowie. Po dodaniu podwójnych cudzysłowów do każdego parametru zaczął on działać zgodnie z oczekiwaniami.Poniżej znajduje się stan mojego kodu przed i w pełni funkcjonujący po stanie.
Przed - niedziałający kod
Po - kod działający
źródło
Najprostszym rozwiązaniem tego problemu jest to, że wystarczy użyć
\"
argumentów oddzielonych spacjami podczas uruchamiania skryptu powłoki:źródło
Twoja definicja myFunction jest błędna. Powinno być:
lub:
W każdym razie wygląda dobrze i działa dobrze dla mnie na Bash 3.2.48.
źródło
Spóźniłem się 9 lat, ale byłby bardziej dynamiczny sposób
źródło
Proste rozwiązanie, które zadziałało dla mnie - cytat $ @
Mogłem zweryfikować faktyczne polecenie grep (dzięki set -x).
źródło
Możesz mieć rozszerzenie tego problemu w przypadku, gdy twój początkowy tekst został ustawiony w zmiennej typu łańcuchowego, na przykład:
W tym przypadku, jeśli nie przekażesz zmiennej status_message naprzód w postaci łańcucha (otoczonego ""), zostanie ona podzielona na szereg różnych argumentów.
„$ variable” : bieżący utwór to CDE w DEF autorstwa ABC
$ zmienna :
źródło
myFunction "firstString" "second string with spaces" "thirdString"
i nie działał dla niego. Więc to, co proponujesz, nie dotyczy tego pytania.Wystąpił ten sam rodzaj problemu iw rzeczywistości problemem nie była funkcja ani wywołanie funkcji, ale to, co przekazałem jako argumenty do funkcji.
Funkcja została wywołana z treści skryptu - 'main' - więc przekazałem "st1 a b" "st2 c d" "st3 e f" z linii poleceń i przekazałem do funkcji używając myFunction $ *
$ * Powoduje problem, ponieważ rozwija się do zestawu znaków, które zostaną zinterpretowane w wywołaniu funkcji przy użyciu białych znaków jako separatora.
Rozwiązaniem była zmiana wywołania funkcji w jawnej obsłudze argumentów z 'main' na funkcję: wywołanie byłoby wtedy myFunction "$ 1" "$ 2" "$ 3", co zachowa spacje wewnątrz łańcuchów, ponieważ cudzysłowy będą ograniczały argumenty ... Więc jeśli parametr może zawierać spacje, powinien być obsługiwany jawnie we wszystkich wywołaniach funkcji.
Ponieważ może to być przyczyną długich poszukiwań problemów, rozsądne może być nigdy nie używanie znaku $ * do przekazywania argumentów ...
Mam nadzieję, że to pomoże komuś kiedyś, gdzieś ... Jan.
źródło
"$@"
nie wszystkie podane"$1"
,"$2"
... pozycyjne paramters ani$*
.