Como "menos" um arquivo chamado "-"?

17

Eu acidentalmente criei um arquivo com o nome -(por exemplo, seq 10 > -). Então eu tentei usar lesspara vê-lo, mas ele simplesmente trava.

Entendo que isso está acontecendo porque less -espera a entrada de stdin, portanto, ele não interpreta o -como um nome de arquivo. Eu tentei, less \-mas também não funciona.

Então, existe alguma maneira de indicar lessque -é um arquivo e não stdin?

O melhor que pude obter é:

find -name '-' -exec less {} +
fedorqui
fonte
2
@ muru obrigado pelo comentário, mas a possível duplicata é tão específica que eu não acho que se qualifique como "exata duplicada". Se ele foi reformulado para algo mais genérico como "como acessar um arquivo começando com '-'", talvez.
Fedorqui
4
Essa não é uma pergunta duplicada. O caso -sozinho é diferente. -não é uma opção.
Stéphane Chazelas
1
@terdon Eu não acho que ter a mesma resposta diretamente significa que eles são duplicados. Havia um exemplo em algum lugar no Meta SO: se uma pergunta for respondida com "Não", qualquer coisa cuja resposta correta seja "Não" será duplicada? Como eu disse antes, seria interessante reformular o candidato de duplicado para que ele seja mais genérico; caso contrário, não faz muito sentido enviar outras perguntas como essa.
Fedorqui 17/06/2015
4
@terdon, não. A solução aceita aqui não funcionará aqui. E não, -não é tratado como uma opção, é um problema totalmente diferente do caso de argumentos que têm a forma de opções.
Stéphane Chazelas
2
Não é necessário delimitar -entre aspas simples '-'ou escapar como, \-porque -não é um caractere especial para shells comuns (pelo menos os compatíveis com POSIX). O resultado é o mesmo.
pabouk

Respostas:

53

Apenas prefixe-o com ./:

less ./-

Ou use o redirecionamento:

less < -

Observe que, como -(ao contrário de -xou --foo--por exemplo) é considerado um nome de arquivo especial e não uma opção, o seguinte não funciona:

less -- -   # THIS DOES NOT WORK
Howard
fonte
3
BTW, é isso que find -name '-' -exec less {} +corre.
Stéphane Chazelas
6
@fedorqui, não, é apenas isso -e ./-(ou /path/to/-ou ../to/-) são dois (4) caminhos válidos para esse -arquivo, mas um -argumento é especial para less(significa ler a partir de stdin) enquanto ./-não é especial.
Stéphane Chazelas
2
@fedorqui find -name '-' -exec less {} +é o formulário não padrão para find . -name '-' -exec less {} +. Ele desce a árvore em .e localiza arquivos e passa os caminhos desses arquivos como argumentos para less. Substitua -exec lesspor -exec echo lesspara ver o que está sendo executado.
Stéphane Chazelas
4
@haylem, --é marcar o final das opções. Não vai ajudar aqui. Isso -não é uma opção, é um argumento especial de não-opção. Veja também unix.stackexchange.com/a/56370 , unix.stackexchange.com/a/110756
Stéphane Chazelas
3
@haylem, tente você mesmo. --é manipulado por getopt () para marcar o final das opções, -não é reconhecido como uma opção por getopt (), de modo que -será reconhecido como um argumento normal, independentemente de --ser fornecido ou não. E como um argumento normal, lesscomo a maioria dos utilitários de texto o tratará como significando stdin, o que não queremos aqui.
Stéphane Chazelas
3

Nota: minha resposta NÃO é válida no caso do OP, e somente se aplica a ferramentas que seguem a convenção mencionada abaixo e não no caso de um arquivo chamado exatamente just -(dash), que geralmente também é um caso especial para especificar essa leitura do padrão entrada é esperada. Veja a resposta aceita.

Deixando isso aqui, pois contém informações úteis para outros casos em que alguém pode se deparar enquanto procura respostas.


Dê um duplo passo!

Use a --convenção double-dash ( ) padrão para indicar o último argumento:

less -- -FILENAME

Exemplo

$ echo "meh" > -badname
$ less -badname
Number is required after -b
$ less -- -badname # GREAT SUCCESS!

Whhhaattt?

Esse --argumento deriva de uma convenção suportada pela maioria das implementações de utilitários de shell e ferramentas de linha de comando, e a maioria dos shells defende visivelmente que você deve segui-lo ao implemente as ferramentas da CLI.

Recomendado pelo Open Group

O OpenGroup também o menciona na seção Padrões de descrição do utilitário (v6) de sua Especificação básica:

Comportamento padrão: Utilitários [...] padrão que não aceitam opções, mas que aceitam operandos, devem reconhecer "-" como o primeiro argumento a ser descartado.

O requisito para reconhecer "-" é porque os aplicativos em conformidade precisam de uma maneira de proteger seus operandos de quaisquer opções arbitrárias que a implementação possa fornecer como uma extensão. Por exemplo, se o utilitário foo padrão estiver listado como não tendo opções e o aplicativo necessário para fornecer um nome de caminho com um hífen à esquerda, ele poderá fazê-lo com segurança como:

foo -- -myfile

e evite qualquer problema com -m usado como uma extensão.

E nas Diretrizes de sintaxe do utilitário (v7):

Diretriz 10: O primeiro argumento que não é um argumento de opção deve ser aceito como um delimitador indicando o fim das opções. Quaisquer argumentos a seguir devem ser tratados como operandos, mesmo se começarem com o caractere '-'.

Recomendado por Bash

Aqui, extraído do manual do bash, sobre os componentes internos que o suportam:

Salvo indicação em contrário, cada comando interno documentado nesta seção como opções de aceitação precedido por - aceita - para significar o final das opções.

Os embutidos:, true, false e test não aceitam opções e não tratam - especialmente. A saída, logout, interrupção, continuação, permissão e mudança dos componentes internos aceitam e processam argumentos começando com - sem exigir -. Outros componentes internos que aceitam argumentos, mas não são especificados como opções de aceitação, interpretam argumentos que começam com - como opções inválidas e requerem - para impedir essa interpretação.

Observe que eco não interpreta - para significar o fim das opções.

Leitura Adicional

haylem
fonte
2
+1: A solução mais portátil e independente de comando, fácil de lembrar e considerada a "melhor prática"
mveroone 17/06/2015
2
@Kwaio alguma referência sobre as "melhores práticas"? Apenas sinta curiosidade sobre isso.
Fedorqui
24
Essa resposta se aplica a argumentos que parecem opções. Não é o caso para o -qual não é uma opção. Usando ./-ou redirecionamento quando possível é geralmente uma abordagem melhor, pois evita outros tipos de problemas, como o foo=barde awkou que -. Veja também unix.stackexchange.com/a/56370 , unix.stackexchange.com/a/110756
Stéphane Chazelas
7
Como diz Stéphane, isso não responde à pergunta. less -- -ainda tentará ler do stdin.
Michał Politowski
5
Você pode excluir a resposta (ou movê-la para a outra pergunta, pois há referências úteis aqui) ou esclarecer que ela não se aplica a esse caso específico (e talvez explicar por que seria ainda mais útil).
Stéphane Chazelas