Por que espaços entre opções e parâmetros podem ser omitidos?

14

Por exemplo:

xargs -n 1

é o mesmo que

xargs -n1

Mas se você olhar para a página man , a opção é listada como -n max-args , o que significa que o espaço deveria ser preservado. Não há nada sobre a forma abreviada -n max-args .

Isso também acontece com muitos outros utilitários do Linux.

O que é isso chamado no Linux? Todos os utilitários suportam o formato abreviado (mas nunca o documentam na página man)?

    
por J.Joe 26.06.2016 / 17:34

2 respostas

12

Quando você escreve o bit de análise do seu código na linha de comando, você especifica quais opções aceitam argumentos e quais não. Por exemplo, em um script de shell aceitando uma opção -h (para ajuda, por exemplo) e uma opção -a que deve receber um argumento, você faz

opt_h=0     # default value
opt_a=""

while getopts 'a:h' opt; do
    case $opt in
        h)  opt_h=1 ;;
        a)  opt_a="$OPTARG" ;;
    esac
done

echo "h: $opt_h"
echo "a: $opt_a"

O a:h bit diz "Estou esperando analisar duas opções, -a e -h e -a devem receber um argumento" (é o : após a que informa ao analisador que -a leva um argumento).

Portanto, nunca há qualquer ambigüidade em onde uma opção termina, onde seu valor é iniciado e onde outra começa depois disso.

Executando:

$ bash test.sh -h -a hello
h: 1
a: hello

$ bash test.sh -h -ahello
h: 1
a: hello

$ bash test.sh -hahello
h: 1
a: hello

É por isso que você na maioria das vezes não deve escrever seu próprio analisador de linha de comando para analisar as opções.

Há apenas um caso neste exemplo que é complicado. A análise geralmente pára na primeira não opção, então quando você tem coisas na linha de comando que parece como opções:

$ bash test.sh -a hello -world
test.sh: illegal option -- w
test.sh: illegal option -- o
test.sh: illegal option -- r
test.sh: illegal option -- l
test.sh: illegal option -- d
h: 0
a: hello

O seguinte resolve isso:

$ bash test.sh -a hello -- -world
h: 0
a: hello

O -- sinaliza um fim de opções de linha de comando e o -world bit é deixado para o programa fazer o que quiser com (está em uma das variáveis posicionais).

Ou seja, como você remove um arquivo que tem um traço no início do nome do arquivo com rm .

EDITAR :

Utilitários escritos em C chamam getopt() (declarado em unistd.h ), que funciona basicamente da mesma maneira. De fato, para todos nós sabemos, a bash function getopts pode ser implementada usando uma chamada para a função da biblioteca C getopt() . Perl, Python e outras linguagens têm bibliotecas similares de análise de linha de comando, e é mais provável que elas realizem sua análise de maneira similar.

Algumas dessas rotinas de biblioteca getopt e getopt -like também lidam com opções "longas". Estes são geralmente precedidos por traço duplo ( -- ), e as opções longas que recebem argumentos geralmente o fazem após um sinal de igual, por exemplo a opção --block-size=SIZE de [algumas implementações] do du utility (que também permite que -B SIZE especifique a mesma coisa).

Os manuais de motivos são frequentemente escritos para mostrar um espaço entre as opções curtas e seus argumentos são provavelmente para legibilidade.

EDITAR : Realmente as ferramentas antigas, como os utilitários dd e tar , têm opções sem traços na frente delas. Isso é puramente por razões históricas e por manter compatibilidade com software que depende deles para trabalhar exatamente dessa maneira. O utilitário tar ganhou a capacidade de escolher opções com traços em tempos mais recentes. O manual do BSD para tar chama as opções antigas para "flags empacotados".

    
por 26.06.2016 / 19:06
4

xargs é um dos utilitários POSIX. Como comentado por @drewbenn, o POSIX documenta o comportamento de análise de opções para a maioria de seus utilitários para corresponder a getopt , com alguns subsídios para outras implementações, dizendo em 12.1 Sintaxe do Argumento de Utilidade :

This section describes the argument syntax of the standard utilities and introduces terminology used throughout POSIX.1-2008 for describing the arguments processed by the utilities.

Within POSIX.1-2008, a special notation is used for describing the syntax of a utility's arguments. Unless otherwise noted, all utility descriptions use this notation, which is illustrated by this example (see XCU Simple Commands):

e concluindo com

It is recommended that all future utilities and applications use these guidelines to enhance user portability. The fact that some historical utilities could not be changed (to avoid breaking existing applications) should not deter this future goal.

Dentro do POSIX (lembre-se que ele cobre apenas os utilitários mais usados), há exceções que passam operandos que seriam opções em outros utilitários como parâmetros posicionais , ou parâmetros com sintaxe especial :

POSIX permite valores de opção opcionais :

Option-arguments are shown separated from their options by <blank> characters, except when the option-argument is enclosed in the '[' and ']' notation to indicate that it is optional.

De improviso, não me lembro quais utilitários POSIX usam o recurso. Os ncurses tic e infocmp usam o recurso níveis da opção -v (verbose / debug).

O ponto específico que você perguntou é detalhado no restante daquele parágrafo, indo em várias linhas.

Antes do POSIX, algumas implementações de ps aceitavam opções sem um hífen principal. A descrição POSIX não menciona isso na descrição do utilitário ou na lógica da sintaxe:

Além do POSIX, existem implementações de opções longas (como o GNU getopt_long ou X Toolkit ), usando uma variedade de maneiras para separar ou associar o valor de uma opção à opção. Por exemplo, a pontuação pode ser usada:

--option=value
--option value

Dependendo da implementação, um traço duplo pode ou não ser usado para distinguir opções longas de curtas (getopt): lynx e o X Toolkit usa um único traço; O GNU getopt_long usa um traço duplo, por exemplo. Além disso, um + pode ser usado para indicar que uma opção é negada.

A descrição do POSIX parece não mencionar nada disso, mas é bem provável que você os encontre.

    
por 26.06.2016 / 22:19

Tags