Jak przekazać wszystkie argumenty przekazane do mojego skryptu bash do mojej funkcji? [duplikat]

to pytanie ma już odpowiedzi tutaj : propaguje wszystkie argumenty w skrypcie powłoki bash (12 odpowiedzi) Zamknięty 1 rok temu .

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?

Author: Amol, 2010-09-28

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ć.

 1133
Author: Gordon Davisson,
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]
 151
Author: hajamie,
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 "$@"
 55
Author: Mia Clarke,
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]}.

 50
Author: Giuseppe Cardone,
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.
 40
Author: robstarbuck,
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 $*"
}
 22
Author: andrew lorien,
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.

 20
Author: Vivien Barousse,
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