2016-06-17 14 views
10

Voglio chiamare/bin/sh, e usare l'opzione -c per passare il comando '+ x' , cioè, per eseguire un programma chiamato '+ x', il cui nome inizia con un segno più.Gestione di '-' in argomenti di/bin/sh: POSIX vs implementazioni di Bash/Dash/FreeBSD's sh

Poiché '+ x' è interpretato da/bin/sh come opzione (in particolare, disabilitare l'opzione 'x'),/bin/sh deve essere impedito dall'interpretarlo come opzione. Ottengo i seguenti risultati diversi a seconda del/bin/sh che uso:

(1) prima variante:

/bin/sh -c -- +x 

Utilizzando Dash e Bash su Linux: viene eseguito il comando + x.

Utilizzo di FreeBSD's sh: il comando - viene eseguito e viene impostata l'opzione + x.

(2) Seconda variante:

/bin/sh -c +x 

Utilizzando Dash e Bash su Linux: Il + x opzione è impostata, e non v'è un errore perché l'opzione -c manca un argomento.

Utilizzo di FreeBSD's sh: il comando + x viene eseguito.

(3) terza variante:

/bin/sh -c - +x 

Utilizzando Dash e Bash su Linux: + x viene eseguito.

Utilizzo di FreeBSD's sh: Il comando - viene eseguito e l'opzione + x è impostata.

(4) quarta variante: (aggiunto come suggerito nei commenti)

/bin/sh -c+x 

Utilizzando Dash e Bash su Linux: Opzione non valida/non valida '+'

Utilizzando sh di FreeBSD: Bad -c opzione


La mia domanda: cosa prescrive POSIX?

sto leggendo le specifiche POSIX per sh qui: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html

Citando da esso: ". Un singolo trattino deve essere trattato come primo operando e poi ignorato Se entrambi '-' e '-' sono dati come argomenti, o se altri operandi precedono il trattino singolo, i risultati non sono definiti. "

Non sono sicuro che questa citazione si applica anche a un trattino collocato subito dopo "-c".

Quindi, quale è giusto, Dash/Bash o FreeBSD? Oppure, se entrambi hanno ragione perché POSIX consente entrambi, come farlo in modo portabile?

+1

Per buona misura: cosa fa '/ bin/sh -c + x'? –

+0

@ vescovo Non la penso così. '/ bin/sh' vedrà solo gli argomenti' -c' e '+ x', quindi' getopt() 'dovrebbe trattarlo come'/bin/sh -c + x'. –

+1

Il riferimento POSIX per 'sh' è qui: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html –

risposta

6

La risposta alla domanda "Che cosa prescrive Posix" è già presente nell'OP. Ma l'importante caratteristica dello standard Posix non è evidenziata: l'opzione -c non accetta un argomento.

si può vedere questo nella Sinossi:

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

Che la bandiera -c fa è causare i parametri posizionali ("operandi") debbano essere interpretati in un modo diverso. Senza -c, vengono interpretati come [command_file [argument...]]:

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

Questo, tra l'altro, e perciò non sh -c+x è un errore. Se -c ha preso un argomento, sarebbe legale includere l'argomento nella stessa parola.

Quindi, per rispondere alle domande più specifiche:

  1. Posix dice "un singolo trattino deve essere trattato come primo operando e poi ignorato ...". Si applica a - immediatamente dopo -c?

    A: Sì, lo fa. -c è un'opzione completa e il - è pertanto un operando. Al contrario, - in -o - non verrà considerato come un operando. (Sarebbe considerato come un nome opzione non valido)

  2. Quale è giusto, Dash/Bash o FreeBSD?

    A: In questo caso, Dash e Bash sono conformi a Posix e FreeBSD non lo è. La shell di FreeBSD anticipa considerevolmente l'attuale specifica Posix, e non credo che si sia mai pretesa di essere pienamente conforme a qualsiasi specifica Posix.

  3. Come faccio portabile uso sh per eseguire un comando il cui nome inizia con un +?

    A: Vorrei pensare il seguente dovrebbe funzionare su qualsiasi shell:

    sh -c " +x" 
    

    " +x" non sarà riconosciuto come opzione, perché non inizia con un + o -, e fa sì che il sh -c operando essere analizzato come un comando di shell, quindi gli spazi iniziali saranno ignorati. Non ho una copia di Free201D di ash per giocare con solo ora, quindi accolgo con favore le correzioni.

    Oppure si potrebbe usare un semplice comando composto:

    sh -c "{ +x; }" 
    

    Possibilmente più chiara (supponendo che il guscio si sta utilizzando attrezzi il Posix standard built command) è:

    sh -c "command +x" 
    
+0

Digita in risposta: '" + x "' -> '" + x "'. – Kusalananda

+0

Stesso discorso: ho pensato che 'sh -c '+ x'' avrebbe funzionato, ma non ho FreeBSD da testare e il commento di @ Rhymoid mi ha dissuaso. Penso che sia stato per il meglio, perché ''+ x'' sembra difficile (e forse fragile). Il comando 'sh -c '+ x'' sembra più chiaro all'intenzione mentre è portatile. – bishop

+0

Se lo spazio è troppo strano, 'sh -c ':; + x'' dovrebbe funzionare anche. – melpomene