2016-06-17 61 views
10

Chcę wywołać/bin/sh i użyć opcji -c, aby przekazać polecenie "+ x" , to znaczy, aby uruchomić program o nazwie "+ x", którego nazwa zaczyna się znakiem plus.Obsługa "-" w argumentach/bin/sh: POSIX vs implementacje Bash/Dash/FreeBSD's sh

Ponieważ "+ x" jest interpretowane jako/bin/sh jako opcja (konkretnie, wyłącz opcję "x"), należy zabronić/bin/sh interpretować ją jako opcję. Mam następujące różne wyniki w zależności od/bin/sh używać:

(1) Pierwszy wariant:

/bin/sh -c -- +x 

Korzystanie Dash a bash na Linux: Komenda + x jest wykonywany.

Korzystanie z funkcji FreeBSD sh: polecenie - jest wykonywane, a opcja + x jest ustawiona.

(2) Drugi wariant:

/bin/sh -c +x 

Korzystanie Dash a bash na Linux: + x opcja jest ustawiona, a tam jest błąd, ponieważ opcja -c brakuje argumentu.

Korzystanie z funkcji FreeBSD: Wykonanie polecenia + x.

(3) Trzeci wariant:

/bin/sh -c - +x 

Korzystanie Dash a bash na Linux: + x jest wykonywany.

Korzystanie z funkcji FreeBSD sh: polecenie - zostaje wykonane i ustawiona jest opcja + x.

(4) Czwarty wariant: (dodany jako sugerowane w komentarzach)

/bin/sh -c+x 

Korzystanie Dash a bash na Linux: Nieprawidłowy/opcja nielegalne '+'

Korzystanie sh FreeBSD: Bad -c opcja


Moje pytanie: co oznacza POSIX?

Czytam specyfikacji POSIX dla sh tutaj: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html

Cytując go: „. Jedna kreska powinna być traktowana jako pierwszego argumentu, a następnie ignorowane Jeśli oba«-»i«-»są podane jako argumenty lub jeśli inne operandy poprzedzają pojedynczy łącznik, wyniki są niezdefiniowane. "

Nie jestem pewien, czy ten cytat dotyczy także pojedynczego myślnika umieszczonego tuż po "-c".

Więc, który z nich ma rację, Dash/Bash lub FreeBSD? Lub, jeśli obie są słuszne, ponieważ POSIX pozwala obu, jak to zrobić przenośnie?

+1

Dla dobra miara: co robi '/ bin/sh -c + x' –

+0

@ Bishop Nie sądzę. '/ bin/sh' zobaczy tylko argumenty' -c' i '+ x', więc' getopt() 'powinno traktować to jako'/bin/sh -c + x'. –

+1

Tutaj znajduje się odnośnik POSIX dla 'sh': http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html –

Odpowiedz

6

Odpowiedź na pytanie "Co nakazuje Posix" jest już obecna w PO. Ale ważna cecha standardu Posix nie jest podświetlona: Opcja nie przyjmuje argumentu.

Widać to w streszczeniu:

sh -c [-abCefhimnuvx] [-o option]... [+abCefhimnuvx] [+o option]... 
     command_string [command_name [argument...]] 

Co flaga -c robi to spowodować parametry pozycyjne („operandów”) należy interpretować w inny sposób. Bez -c, są one interpretowane jako [command_file [argument...]]:

sh [-abCefhimnuvx] [-o option]... [+abCefhimnuvx] [+o option]... 
    [command_file [argument...]] 

To, nawiasem mówiąc, to dlaczego sh -c+x jest błąd. Jeśli -c zajął argument, byłoby to zgodne z prawem uwzględnienie argumentu w tym samym słowie.

Tak więc, aby odpowiedzieć na bardziej szczegółowe pytania:

  1. POSIX mówi „Jeden łącznik powinien być traktowany jako pierwszy argument, a następnie ignorować ...”. Czy to dotyczy - bezpośrednio po -c?

    O: Tak, tak. -c jest kompletną opcją, a - jest operandem. W przeciwieństwie do tego, - w -o - nie będą traktowane jako operand. (Będzie traktowany jako niepoprawna nazwa opcji).

  2. Który z nich jest prawidłowy, Dash/Bash lub FreeBSD?

    Odp .: W tym przypadku Dash i Bash są zgodne z Posix, a szuflada FreeBSD nie jest. Powłoka FreeBSD znacznie wyprzedza obecną specyfikację Posix i nie sądzę, aby kiedykolwiek była zgodna z jakąkolwiek specyfikacją Posix.

  3. Jak mogę przenośnie użyć sh, aby uruchomić polecenie, którego nazwa zaczyna się od +?

    A: Myślę dodaje będzie działać na każdej powłoki:

    sh -c " +x" 
    

    " +x" nie zostanie rozpoznany jako opcja, ponieważ nie zacząć + lub - i sh -c powoduje operand parsowane jako polecenie powłoki, więc wiodące białe znaki będą ignorowane. Nie mam kopii FreeBSD's ash, aby grać właśnie teraz, więc przyjmuję poprawki.

    Albo można użyć prostego polecenia związek:

    sh -c "{ +x; }" 
    

    Prawdopodobnie najczystszy (zakładając powłoki używasz implementuje standard POSIX wbudowanych command) wynosi:

    sh -c "command +x" 
    
+0

Typo w odpowiedzi: '" + x "' -> '" + x "'. – Kusalananda

+0

To samo tutaj: Myślałem, że 'sh -c '+ x'' zadziała, ale nie mam FreeBSD do przetestowania i komentarz @ Rhymoid zniechęcił mnie. Myślę, że to było na lepsze, ponieważ '' + x'' wydaje się trudne (i może kruche). Komenda 'sh -c '+ x'' wydaje się bardziej przejrzysta w zamierzeniu będąc przenośną. – bishop

+0

Jeśli przestrzeń jest zbyt dziwna, 'sh -c ':; + x'' również powinno działać. – melpomene