2012-01-29 14 views
269

Mam prosty skrypt, w którym pierwszy argument jest zarezerwowany dla nazwy pliku, a wszystkie inne opcjonalne argumenty powinny zostać przekazane do innych części skryptu.Przetwarzaj wszystkie argumenty oprócz pierwszego (w skrypcie basha)

Korzystanie z Google znalazłem this wiki, ale pod warunkiem dosłownego przykład:

echo "${@: -1}" 

nie mogę nic innego do pracy, jak:

echo "${@:2}" 

lub

echo "${@:2,1}" 

Dostaję "złe zastąpienie" z terminala.

Na czym polega problem i jak mogę przetworzyć wszystkie oprócz pierwszego argumentu przekazanego do skryptu Bash?

+4

Aby wywołać jeszcze kogoś zagubionego, podano niewłaściwy kod shebang, który powodował, że '{@: 2}" nie działał, dlatego poprawna odpowiedź pasuje do powyższych. – Guvante

+2

Właśnie użyłeś domyślnej powłoki, która jest myślnikiem na Ubuntu i wielu innych Linuxach. W myślniku "$ {@: -1}" interpretuje się jako: {parametr: -word} - Użyj wartości domyślnych i użyj słowa, jeśli parametr nie jest zdefiniowany lub jest pusty. Tak więc w myślniku "$ {@: -1}" wyniki są dokładnie takie same jak "$ @". Aby użyć bashu, wystarczy użyć następującego pierwszego wiersza w pliku skryptu: #!/Bin/bash – luart

Odpowiedz

376

Użyj tego:

echo "${@:2}" 

następującą składnię:

echo "${*:2}" 

będzie działać jak dobrze, ale nie jest to zalecane, ponieważ jak @Gordon już wyjaśniono, że za pomocą *, działa wszystkie argumenty razem jako pojedynczy argument ze spacjami, podczas gdy @ zachowuje przerwy między nimi (nawet jeśli niektóre z argumentów same zawierają w przestrzeni). Nie ma to znaczenia z echo, ale ma znaczenie dla wielu innych poleceń.

+2

Po prostu zdałem sobie sprawę, że mój shebang był zły: '#!/Usr/bin/env sh' Dlatego właśnie miałem problemy.Przykład działa dobrze, tak jak podano powyżej, po usunięciu tego shebang – theta

+92

Zamiast tego użyj '" $ {@: 2} "- użycie' * 'uruchamia wszystkie argumenty razem jako pojedynczy argument ze spacjami, podczas gdy' @ 'zachowuje przerwy między nimi (nawet jeśli niektóre z nich zawierają spacje). Różnica nie jest zauważalna w przypadku "echa", ale ma znaczenie dla wielu innych rzeczy. –

+0

@GordonDavisson Chodzi o to, aby uruchomić razem argumenty. Gdybyśmy przekazywali nazwy plików, byłbyś poprawny. "echo" jest wystarczająco wybaczające, aby je połączyć; inne polecenia mogą nie być tak miłe. Nie używaj tylko jednego lub drugiego: dowiedz się, jaka jest różnica między '*' i '@' oraz kiedy używać każdego z nich. Powinieneś ich używać w przybliżeniu. Dobrym przykładem tego, kiedy to będzie problem: jeśli '$ 3' zawiera podział wiersza (' \ n'), zostanie zastąpiony spacją, pod warunkiem, że masz domyślną zmienną '$ IFS'. – Zenexer

121

Jeśli chcesz rozwiązanie, które działa również w /bin/sh spróbować

first_arg="$1" 
shift 
echo First argument: "$first_arg" 
echo Remaining arguments: "[email protected]" 

shift [n] przesuwa parametry pozycyjne n razy. Wartość shift ustawia wartość $1 na wartość $2, wartość $2 na wartość $3 itd., Zmniejszając wartość o $# o jeden.

+21

+1: Prawdopodobnie powinieneś zapisać 1 $ w zmiennej przed jej przesunięciem. –

+3

Zaskakująco 'foo = shift' nie robi tego, czego bym się spodziewał. –

+0

Wiem, że to jest stare, ale spróbuj 'foo = $ (shift)' –

Powiązane problemy