Jak przekazać wszystkie argumenty przekazane do mojego skryptu bash do mojej funkcji? [duplikat]
Załóżmy, że zdefiniowałem function abc()
, który będzie obsługiwał logikę związaną z analizą argumentów przekazywanych do mojego skryptu.
Jak mogę przekazać do niego wszystkie argumenty, które otrzymał skrypt bash? Liczba paramów jest zmienna, więc nie mogę po prostu zakodować argumentów przekazywanych w ten sposób:
abc $1 $2 $3 $4
Edit . Jeszcze lepiej, czy jest jakiś sposób, aby moja funkcja miała dostęp do zmiennych argumentów skryptu?
7 answers
Zmienna $@
rozszerza się do wszystkich parametrów wiersza poleceń oddzielonych spacjami. Oto przykład.
abc "$@"
Podczas używania $@
, powinieneś (prawie) zawsze umieszczać go w cudzysłowach, aby uniknąć błędnego porównywania argumentów zawierających spacje lub symbole wieloznaczne(patrz poniżej). Działa to dla wielu argumentów. Jest również przenośny dla wszystkich powłok zgodnych z POSIX.
Nie jest też nic warte to, że $0
(ogólnie nazwa skryptu lub ścieżka) nie jest w $@
.
The Bash Reference Sekcja Manual Special Parameters mówi, że $@
rozszerza się do parametrów pozycyjnych zaczynając od jedynki. Gdy rozszerzenie występuje w podwójnych cudzysłowach, każdy parametr rozszerza się do osobnego słowa. To {[6] } jest równoważne "$1" "$2" "$3"...
.
Podanie niektórych argumentów:
Jeśli chcesz przekazać wszystkie argumenty oprócz pierwszych, możesz najpierw użyć shift
, aby "pochłonąć" pierwszy argument, a następnie przekazać "$@"
, aby przekazać pozostałe argumenty do innego polecenia. W bash (oraz zsh i ksh, ale nie w zwykłych powłokach POSIX, takich jak dash), możesz to zrobić bez mieszania się z listą argumentów, używając wariantu wycinania tablic: "${@:3}"
wyświetli argumenty zaczynające się od "$3"
. "${@:3:4}"
da ci do czterech argumentów zaczynających się od "$3"
(tj. "$3" "$4" "$5" "$6"
), jeśli taka liczba argumentów została przekazana.
Rzeczy, których prawdopodobnie nie chcesz robić:
"$*"
podaje wszystkie argumenty sklejone razem w jeden łańcuch (oddzielony spacjami, czy jakakolwiek pierwsza znak $IFS
jest). Powoduje to utratę rozróżnienia między spacjami Wewnątrz argumentów i spacjami pomiędzy argumentami, więc jest to ogólnie zły pomysł. Chociaż drukowanie argumentów może być w porządku, np. echo "$*"
, pod warunkiem, że nie zależy ci na zachowaniu przestrzeni wewnątrz / między rozróżnieniami.
Przypisanie argumentów do zwykłej zmiennej (jak w args="$@"
) masuje wszystkie argumenty razem, tak jak robi to "$*"
. Jeśli chcesz zapisać argumenty w zmiennej, użyj tablica z args=("$@")
(nawiasy czynią ją tablicą), a następnie odwołaj się do nich jako np. "${args[0]}"
itd (zauważ, że indeksy tablic bash zaczynają się od 0, więc {[22] } będzie w args[0]
, itd).
Pomijając podwójne cudzysłowy, z $@
lub $*
, spróbuje podzielić każdy argument na osobne słowa (w oparciu o spacje lub cokolwiek w $IFS
), a także spróbować rozwinąć wszystko, co wygląda jak symbol wieloznaczny do listy pasujących nazw plików. To może mieć naprawdę dziwne efekty i należy prawie zawsze unikać.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-08 07:52:36
Potrzebowałem wariacji na ten temat, która spodziewam się, że będzie przydatna dla innych:
function diffs() {
diff "${@:3}" <(sort "$1") <(sort "$2")
}
Część "${@:3}"
oznacza wszystkie elementy tablicy zaczynające się od 3. Tak więc ta funkcja implementuje posortowane rozróżnienie, przekazując dwa pierwsze argumenty do diff poprzez sort, a następnie przekazując wszystkie inne argumenty do diff, więc możesz wywołać go podobnie do diff:
diffs file1 file2 [other diff args, e.g. -y]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-17 16:05:27
Użyj zmiennej $@
, która rozszerza się na wszystkie parametry wiersza poleceń oddzielone spacjami.
abc "$@"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-29 17:51:56
Oto prosty skrypt:
#!/bin/bash
args=("$@")
echo Number of arguments: $#
echo 1st argument: ${args[0]}
echo 2nd argument: ${args[1]}
$#
jest liczbą argumentów otrzymanych przez skrypt. Łatwiej jest uzyskać do nich dostęp za pomocą tablicy: linia args=("$@")
umieszcza wszystkie argumenty w tablicy args
. Aby uzyskać do nich dostęp, użyj ${args[index]}
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-10 12:44:23
Warto wspomnieć, że za pomocą tej składni można określić zakresy argumentów.
function example() {
echo "line1 ${@:1:1}"; #First argument
echo "line2 ${@:2:1}"; #Second argument
echo "line3 ${@:3}"; #Third argument onwards
}
Nie widziałem, żeby o tym wspominano.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-22 23:24:43
Abc "$ @ " jest generalnie poprawną odpowiedzią.
Ale próbowałem przekazać parametr do polecenia su i żadna ilość cytowań nie mogła zatrzymać błędu su: unrecognized option '--myoption'
. To, co naprawdę zadziałało, to przekazywanie wszystkich argumentów jako pojedynczy ciąg znaków :
abc "$*"
Mój dokładny przypadek (jestem pewien, że ktoś inny tego potrzebuje) był w moim .bashrc
# run all aws commands as Jenkins user
aws ()
{
sudo su jenkins -c "aws $*"
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-16 00:34:24
abc "$@"
$@
reprezentuje wszystkie parametry podane do skryptu bash.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-09 10:09:32