tar e suas letras principais: é um bug ou recurso?

18

Estou pensando em perguntar a diferença desses dois comandos (ou seja, apenas a ordem de suas opções é diferente):

  1. tar -zxvf foo.tar.gz
  2. tar -zfxv foo.tar.gz

O primeiro funcionou perfeitamente, mas o segundo disse:

tar: You must specify one of the `-Acdtrux' or `--test-label'  options
Try `tar --help' or `tar --usage' for more information.

E alcatrão --test-labele -zfxvdisse:

tar (child): xv: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now

Então eu olhei para o tar manual e percebi que todo o exemplo lá está usando switch -fno final !!

AFAICT não há necessidade dessa restrição, ou existe ?! porque, na minha opinião, os switches devem ser livres de pedidos.

khikho
fonte
2
@schily sua "correção" nas linhas de comando obscureceu qual comando ele realmente digitou. Um traço principal altera o comportamento do GNU tar para usar um analisador de argumentos diferente. Usando nenhum traço (e, portanto, o analisador de argumentos tradicional), o segundo comando teria funcionado.
usar o seguinte código
A impressão em delta do sistema da web me disse que você ou alguém antes adicionou o -, então eu o removi novamente para corresponder ao que o sistema me disse que era do OP. Mas se você estiver certo gtar option parsing, descobriu outra razão para não usar o gtar.
schily
11
-fespera que o nome do arquivo seja seguido. Na sua segunda versão, você especificou -fxv, o que - para tar - significa que o nome do arquivo é "xv".
Rolf
11
XKCD obrigatório .
Pavel

Respostas:

11

Observando sua mensagem de erro, é óbvio que você não usou, tarmas sim gtar.

Em geral, isso pode ajudar a entender as coisas:

  • tarnormalmente sempre precisa de um argumento de arquivo. Se estiver faltando, ele lerá / gravará de / no dispositivo de fita real padrão do sistema. starmudou isso em 1982 para usar stdin / stdout por padrão e algumas outras implementações tar (por exemplo, gtar) seguiram este exemplo recentemente.

  • tarnão implementa as principais -opções que são chamadas key lettersno caso do comando tar. Algumas implementações foram adicionadas posteriormente -como uma carta-chave não operacional para a conveniência dos usuários, mas você não pode confiar nisso.

  • A maneira como taranalisa seus argumentos (em particular o argumento do arquivo morto) é altamente arriscada. Eu já vi muitos arquivos tar que destruíram um dos arquivos que deveriam estar no arquivo porque o argumento do arquivo relacionado foi tomado como arquivo tar. starpor esse motivo (se chamado nativamente como star) não permite que "f" seja concatenado com outras opções. Se starfor chamado tar, implementa a compatibilidade da linha de comando com tar, mas ainda lida com o argumento da letra "f" de maneira diferente: o argumento só é permitido se se referir a um arquivo de dispositivo real ou quando (no modo de gravação) o arquivo ainda não existe .

Eu recomendo evitar a arriscada linha de comando tar original e usar a sintaxe moderna e segura da linha de comando que você utiliza star.

Por causa da sintaxe problemática da linha de comando tar, havia as chamadas tar warsno início dos anos 90. Como resultado, o programa pax(latim para "paz" nas guerras do alcatrão) foi criado e padronizado. paxno entanto, não ganhou popularidade, pois sua sintaxe é menos arriscada, mas também menos intuitiva que a sintaxe tar. Outro problema pode ser que gpaxé mais ou menos inalterado.

esperto
fonte
3
As guerras do alcatrão terminaram. Guntar venceu.
Joshua
2
Se você estava certo, por que todas as implementações de tar copiam recursos star?
schily
11
Entre: as guerras do alcatrão têm sido uma batalha entre tare cpio.
schily
2
OK, então parece staré -f"$file"também é (além de ind) um problema com nomes de arquivos começando com =. Então é preciso escrevê-lo -f="$file"ou -f "$file". Não sei se chamaria sua opção de estrela de mais segura ou moderna .
Stéphane Chazelas
3
-longopções longas de estilo são incompatíveis com -xyzopções curtas condensadas ou -xarg. É por isso que as opções longas do estilo X11 exigem que as opções curtas sejam separadas ( -x -y, não -xy) e os argumentos das opções estejam em argumentos separados ( xterm -n foo, não xterm -nfoo). E é por isso que há um traço extra nas opções longas do GNU, para remover a possível confusão com opções curtas e por que as opções longas no estilo GNU são um design melhor. Você pode -fooconviver -x -y -xyapenas se tiver muito cuidado para evitar as sobreposições.
Stéphane Chazelas
55

A ordem das opções é gratuita, mas -fpossui um argumento obrigatório, que é o arquivo que tarserá de leitura / gravação.

Você poderia fazer

tar -zf foo.tar.gz -xv

e isso funcionará e tem sua exigência de uma ordem não específica de comutadores.

É assim que todos os comandos que têm opções com argumentos funcionam.

Wurtel
fonte
5
O Tar não funciona como outros comandos, pois usa um analisador de linha de comando muito mais antigo - o mesmo usado no comando "ar" e no comando "ps" antigo (pré-POSIX).
schily
11
Obrigado por isso, a resposta selecionada, embora completa, não me permitiu realmente ver qual era o problema especificamente. Em retrospecto, parece óbvio a partir do alcatrão mensagem de erro indicando estava tentando ler o arquivo 'xv'
Josh Rumbut
11
Acredito que você também pode declarar como -f=./myfile, isto é, f assume um valor, não é uma bandeira, é uma entrada.
ThorSummoner
14

Tradicionalmente, as opções do alcatrão são mais ou menos "sem pedidos" (a ordem das opções fe bé importante se ambas forem especificadas). Usar um traço à esquerda, no entanto, faz com que o GNU tar analise as opções de uma maneira considerada mais consistente com outros comandos, onde especificar uma opção que exija um argumento (como o nome do arquivo para f) consumirá imediatamente o restante da "palavra", se houver, como o argumento (tradicionalmente, tar usa a próxima palavra como tamanho do nome do arquivo / bloco quando fou bé especificado). No seu caso, tomou "xv" como o nome do arquivo.

Esse comportamento não pode ser invocado para a portabilidade, no entanto. Para máxima portabilidade, evite usar um traço, sempre coloque por fúltimo e sempre coloque um espaço entre fe o nome do arquivo. Essa é, no entanto, uma simplificação que se quebra se você precisar da bopção ou, em geral, qualquer opção (como C) fque não seja a que exige um argumento.

Isso está documentado na seção Manual do alcatrão "Os três estilos de opção" . Algumas outras implementações (por exemplo, FreeBSD) se referem às opções de estilo antigo como uma "palavra de opção empacotada". E, é claro, algumas implementações podem suportar apenas esse tipo de opção e podem ou não ignorar um traço, se incluídas. Essa é a única forma de chamada especificada na Especificação Unix Única e, portanto, garantida para funcionar em quase todos os sistemas.

Random832
fonte
2
Observe que algumas implementações suportam outras opções com argumentos (como Cno tar BSD ou GNU. O tar schily o suporta como -C, mas não como C, todos suportam como -C).
Stéphane Chazelas
0

No alcatrão, o - nos interruptores foi substituído há muitos anos e não é mais necessário. Tar realmente costumava lhe dizer isso, mas não o faz mais.

ie:
tar zxvf foo.tar.gz
tar zfxv foo.tar.gz

Both of these work fine without the -.
Paulo
fonte