Cómo “menos” un archivo con el nombre “-”?

17

Accidentalmente creé un archivo con el nombre -(por ejemplo, seq 10 > -). Luego traté de usar lesspara verlo, pero simplemente se cuelga.

Yo entiendo que esto está sucediendo porque less -la entrada espera de stdin, por lo que no interpreta el -nombre de un archivo. He intentado less \-pero no funciona bien.

Así que, ¿hay alguna manera para indicar lessque -es un archivo y no StdIn?

Lo mejor que pude conseguir es:

find -name '-' -exec less {} +
fedorqui
fuente
2
@muru gracias por el comentario, pero el posible duplicado es tan específico que no creo que sea "duplicado exacto". Si se reformuló a algo más genérico como "la forma de acceder a un archivo que comienza con '-'", tal vez.
fedorqui
44
Esa no es una pregunta duplicada. El caso de -solo es diferente. -no es una opinión.
Stéphane Chazelas
1
@terdon No creo que tener la misma respuesta directamente signifique que son duplicados. Hubo un ejemplo en alguna parte en el Meta SO: si una pregunta se contesta con un "No", haría cualquier cosa cuya respuesta correcta es "no" sea un duplicado? Como he dicho antes, sería interesante volver a redactar el candidato de manera duplicada que es más genérico; de lo contrario, no tiene mucho sentido enviar otras preguntas como esta.
fedorqui
44
@terdon, no. La solución aceptada allí no funcionará aquí. Y no, -no se trata como una opción, que es un problema totalmente diferente del caso de los argumentos que pasan a tener la forma de opciones.
Stéphane Chazelas
2
No es necesario encerrar -entre comillas simples como '-'o escapar \-porque -no es un carácter especial para shells comunes (al menos los que cumplen con POSIX). El resultado es el mismo.
pabouk

Respuestas:

53

Solo prefijalo con ./:

less ./-

O use la redirección:

less < -

Tenga en cuenta que dado que -(a diferencia de -x, o --foo--por ejemplo) se considera un nombre de archivo especial en lugar de una opción, el siguiente no funciona:

less -- -   # THIS DOES NOT WORK
Howard
fuente
3
Por cierto, eso es lo que find -name '-' -exec less {} +corre.
Stéphane Chazelas
66
@fedorqui, no es sólo que -y ./-(o /path/to/-o ../to/-) son dos (4) caminos válidos a que -el archivo, sino un -argumento es especial para less(medios leen de la entrada estándar), mientras que ./-no es especial.
Stéphane Chazelas
2
@fedorqui find -name '-' -exec less {} +es la forma no estándar para find . -name '-' -exec less {} +. Desciende el árbol .y encuentra archivos y pasa las rutas de esos archivos como argumentos a less. Reemplazar -exec lesscon -exec echo lessver lo que está siendo ejecutado.
Stéphane Chazelas
44
@haylem, --es marcar el final de las opciones. No ayudará aquí. Esa -no es una opción, es un argumento especial sin opción. Ver también unix.stackexchange.com/a/56370 , unix.stackexchange.com/a/110756
Stéphane Chazelas
3
@haylem, pruébalo por ti mismo. --es manejado por getopt () para marcar el final de las opciones, -no es reconocido como una opción por getopt (), por lo que -será reconocido como un argumento normal si --se proporciona o no. Y como argumento normal, lesscomo la mayoría de las utilidades de texto lo tratarán como un stdin que significa, que no queremos aquí.
Stéphane Chazelas
3

Nota: mi respuesta NO es válida en el caso del OP, y solo se aplica a las herramientas que siguen la convención mencionada a continuación y no en el caso de un archivo llamado exactamente solo -(guión), que a menudo también es un caso especial para especificar esa lectura del estándar se espera entrada Ver la respuesta aceptada.

Dejando esto aquí, ya que contiene información útil para otros casos que uno puede tropezar durante la búsqueda de respuestas.


Doble Dash it!

Use la convención estándar de doble guión ( --) para indicar el último argumento:

less -- -FILENAME

Ejemplo

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

Whhhaattt?

Este --argumento se deriva de un convenio con el apoyo de la mayoría de las implementaciones de utilidad de shell y herramientas de línea de comandos, y la mayoría de las cáscaras visiblemente defender que debe seguir cuando implemeing herramientas de CLI.

Recomendado por el Grupo Abierto

El OpenGroup también menciona que en la descripción Utilidad de valores predeterminados de la sección (v6) de su especificación Base:

Comportamiento predeterminado: las [...] utilidades estándar que no aceptan opciones, pero que aceptan operandos, reconocerán "-" como un primer argumento a descartar.

El requisito para el reconocimiento "-" se debe a que las aplicaciones conformes necesitan una manera de proteger a sus operandos de las opciones arbitrarias que la aplicación puede proporcionar como una extensión. Por ejemplo, si la utilidad estándar foo aparece como sin opciones, y la aplicación necesita darle un nombre de ruta con un guión inicial, podría hacerlo de manera segura como:

foo -- -myfile

y evitar cualquier problema con -m utilizado como una extensión.

Y en la sintaxis Directrices Utilidad (v7):

Pauta 10: El primer argumento que no es un argumento de opción debe aceptarse como un delimitador que indica el final de las opciones. Los siguientes argumentos deben tratarse como operandos, incluso si comienzan con el carácter '-'.

Recomendado por Bash

Aquí, extraído del manual de bash, sobre sus componentes incorporados que lo respaldan:

A menos que se indique lo contrario, cada comando incorporado documentado en esta sección acepta opciones precedidas por - acepta - para indicar el final de las opciones.

Las:, verdadero, falso y prueba incorporadas no aceptan opciones y no tratan, especialmente. La salida, cerrar sesión, interrumpir, continuar, dejar y cambiar incorporados aceptan y procesan argumentos que comienzan con, sin requerir,. Otros componentes incorporados que aceptan argumentos pero no se especifican como opciones de aceptación interpretan los argumentos que comienzan con, como opciones no válidas y requieren, para evitar esta interpretación.

Tenga en cuenta que el eco no interpretan - a significa el fin de opciones.

Lectura adicional

haylem
fuente
2
+1: La solución más portátil e independiente del comando, fácil de recordar y considerada la "mejor práctica"
mveroone
2
@Kwaio alguna referencia sobre la "mejor práctica"? Solo siente curiosidad al respecto.
fedorqui
24
Esa respuesta se aplica a los argumentos que se parecen a las opciones. No es el caso para -el cual no es una opción. Usar ./-o redireccionar cuando sea posible es generalmente un mejor enfoque, ya que evita otros tipos de problemas como el foo=barde awko ese -. Ver también unix.stackexchange.com/a/56370 , unix.stackexchange.com/a/110756
Stéphane Chazelas
77
Como dice Stéphane, esto no responde la pregunta. less -- -aún intentará leer desde stdin.
Michał Politowski
55
Es posible que desee eliminar la respuesta (o moverla a la otra pregunta ya que hay referencias útiles aquí) o dejar en claro que no se aplica a este caso en particular (y tal vez explicar por qué lo que sería aún más útil).
Stéphane Chazelas