2009-11-10 5 views
24

Man aktualizacja bash mówi dotyczące opcji -c:nie wydaje się użyć opcji -c bash z argumentami po Opcja -c ciąg

-c string
Jeśli opcja -c jest obecny, to polecenia są odczytywane z string. Jeśli istnieją argumenty po ciągu znaków, są one przypisane do parametrów pozycyjnych , począwszy od $0.

Więc biorąc pod uwagę, że opis, to myślę, że coś jak to powinno działać:

bash -c "echo arg 0: $0, arg 1: $1" arg1 

ale wyjście tylko pokazuje następujący więc wygląda na to argumenty po ciąg -c nie są przypisane do parametry pozycyjne.

arg 0: -bash, arg 1: 

Używam dość starożytną bash (na Fedorze 4):

[root @ dd42 pnia] # bash --version
GNU bash, wersja 3.00.16 (1) - uwalnianiu (i386-RedHat-linux-gnu)
Copyright (C) 2004 Free Software Foundation, Inc.

Co ja naprawdę staramy się robić o to, aby wykonać trochę skrypt powłoki z argumentów. Myślałem, że -c wygląda bardzo obiecująco, stąd powyższy problem. Zastanawiałem się nad używaniem eval, ale nie sądzę, żebym mógł przekazać argumenty do rzeczy, które następują po eval. Jestem też otwarty na inne sugestie.

Odpowiedz

31

Musisz użyć pojedynczych cudzysłowów, aby zapobiec interpolacji w powłoce wywołującej.

$ bash -c 'echo arg 0: $0, arg 1: $1' arg1 arg2 
arg 0: arg1, arg 1: arg2 

Lub uciec zmienne w ciągu cudzysłowu. Które z nich użyć może zależeć dokładnie od tego, co chcesz umieścić w swoim fragmencie kodu.

4

Ponieważ "$0" i "$1" w łańcuchu jest zastąpione odpowiednio zmienną # 0 i # 1.

Spróbuj:

bash -c "echo arg 0: \$0, arg 1: \$1" arg0 arg1

W tym kodzie $ obu są uciec więc baza zobaczyć go jako ciąg $ i nie dać się zastąpić.

Wynikiem tego polecenia jest następująca:

arg 0: arg0, arg 1: arg1

Nadzieja to pomaga.

2

Dodaj ukośnik odwrotny do $0 (tj. \$0), w przeciwnym razie twoja obecna powłoka ucieknie $0 do nazwy powłoki, zanim dotrze do podpowłoki.

2

oknówka ma rację co do interpolacji: należy użyć pojedynczych cudzysłowów.Ale pamiętaj, że jeśli próbujesz przekazać argumenty do polecenia, które jest wykonywane w ciągu ciąg, musisz je przekazać jawnie. Na przykład, jeśli masz skrypt foo.sh jak:

#!/bin/bash 
echo 0:$0 
echo 1:$1 
echo 2:$2 

Następnie należy nazwać jak ten:

$ bash -c './foo.sh ${1+"[email protected]"}' foo "bar baz" 
0:./foo.sh 
1:bar baz 
2: 

lub bardziej ogólnie bash -c '${0} ${1+"[email protected]"}' <command> [argument]...

Not like this:

$ bash -c ./foo.sh foo "bar baz" 
0:./foo.sh 
1: 
2: 

Nor like this:

$ bash -c './foo.sh [email protected]' foo "bar baz" 
0:./foo.sh 
1:bar 
2:baz 

Oznacza to, że można przejść w argumenty podprocesów bez osadzania ich w ciąg poleceń, bez martwienia się o ich ucieczce.