O que significa traço “-” no final de um comando?

78

Dado o seguinte comando:

gzip -dc /cdrom/cdrom0/file.tar.gz | tar xvf 

O que significa o -final do comando? É algum tipo de espaço reservado?

Eugene S
fonte
3
Um pequeno detalhe a ser mencionado: o -not precisa estar no final do comando. Por exemplo: ls -l | diff - /old_ls_output.txt.
Manatwork

Respostas:

82

Nesse caso, significa 'entrada padrão'. É usado por alguns softwares (por exemplo tar) quando um argumento de arquivo é necessário e você precisa usar stdin. Não é uma construção de shell e depende do programa que você está usando. Verifique a página de manual em caso de dúvida!

Nesse caso, a entrada padrão é o argumento para a -fopção Nos casos em que -não há suporte, você pode usar algo como tar xvf /proc/self/fd/0ou tar xvf /dev/stdin(o último é amplamente suportado em vários departamentos).

Não confie nisto para significar 'entrada padrão' universalmente. Como não é interpretado pelo shell, todo programa é livre para lidar com ele como quiser. Em alguns casos, é saída padrão ou algo completamente diferente: susignifica 'iniciar um shell de login'. Em outros casos, não é interpretado. A memória muscular me fez criar vários arquivos com o nome -porque alguma versão de algum programa que eu estava acostumado a não entender o traço.

Alexios
fonte
4
Também pode significar STDOUT, dependendo do contexto.
bahamat
3
E praticamente qualquer outra coisa, pois depende de programas individuais para interpretar.
Alexios28:
5
/dev/stdinou /dev/stdoutpode ser usado se você realmente deseja um fluxo de entrada / saída. Note que é um fluxo, os programas que querem buscar em um arquivo podem não funcionar corretamente com ele como seria o caso de -(por exemplo, ffmpeg)
Lekensteyn
3
No caso de bash, o hífen é interpretado pelo shell. Consulte o Advanced Bash-Scripting Guide - Capítulo 3. Caracteres Especiais e procure o texto [traço] ou "redirecionamento de / para stdin ou stdout". Usando bashvocê pode usar o hífen na maioria dos lugares que esperam um nome de arquivo. É um complemento óbvio para <| > IMHO
bsd
4
Não estou convencido de que seja o caso. Primeiro, catidentificadores -(verifique a página de manual). Uma versão interna do shell catpode ou não, mas não é estritamente o shell inteiro. Além disso, se o shell fosse manipulado -, você poderia dizer eco -e expandiria para outra coisa. Em vez disso, apenas ecoa um traço (não /dev/stdinou /proc/self/fd/0). E echo test > -apenas cria um arquivo chamado -, para que ele claramente também não o lide. Ah, e a página que você listou não diz que é manipulada pelo shell , mas sim que você pode usá-lo com cate diff, os quais entendem os traços explicitamente.
Alexios
13

Nesse caso, ele -é realmente inútil, supondo que você esteja executando o Linux:

O GNU tar (a versão no Linux) aceita sua entrada da entrada padrão por padrão. Se você não deseja esse comportamento e deseja passar o nome do arquivo como argumento de linha de comando, precisará especificar o sinalizador f:

tar xf filename

Então isso é o mesmo que

tar x < filename

Ou, se a entrada for compactada como no seu exemplo:

gzip -dc filename | tar x

Não é significativo especificar a fsinalização aqui, mas como foi especificado, o nome do arquivo precisa ser fornecido -para indicar que queremos ler da entrada padrão (consulte outra resposta). Então, repetindo, isso é redundante e um pouco estranho.

Além disso, a linha acima pode ser simplificada porque o tar do GNU pode ser instruído a transmitir a entrada através de gzipsi mesma, especificando o zsinalizador:

tar xfz filename

- Não há necessidade de ligar gzipexplicitamente.

Konrad Rudolph
fonte
1
Nota: nem todos tartêm zopção.
Liori 28/06/12
2
A maioria dos sistemas operacionais diferentes do Linux tem como tarpadrão a primeira unidade de fita, por motivos históricos.
Gilles
1
@Gilles e BSD e OS X,…. Mas estou curioso: que outros sistemas, exceto em alguns mainframes antigos, ainda usam essa versão (quais sistemas, exceto os mainframes, têm uma unidade de fita)?
Konrad Rudolph
1
@KonradRudolph Todos os três principais BSDs são padrão para uma unidade de fita ( /dev/sa0no FreeBSD 9.0, /dev/rst0no NetBSD 6.0 e no OpenBSD 5.1). O AIX 7.1 é padronizado como /dev/rmt0. O padrão MINIX3 é /dev/sa0. (Eu verifiquei a versão mais recente do sistema operacional em cada caso, esses não são “mainframes antigos”.) O Solaris é configurável por meio de um arquivo /etc, que eu acho padrão como uma unidade de fita. Alcatrão GNU, alcatrão Schilling, OSX e BusyBox padrão para stdin / stdout.
Gilles
1
@ Gilles - recompilei o tarpadrão para a segunda unidade de fita, por razões óbvias. :)
David Harkness