Use um caminho explícito para o arquivo:
touch ./-
cat ./-
O GNU touch trata um operando de arquivo de - especialmente:
A FILE argument string of
-is handled specially and causestouchto change the times of the file associated with standard output.
Para cat , o padrão POSIX especifica que um operando de arquivo - deve ser interpretado como um pedido para ler da entrada padrão.
A convenção de dois passos ainda está em vigor, mas não é para sinalizar o fim de argumentos , mas o fim de opções . Em nenhum desses casos, - seria tomado como uma opção (um único - não pode ser uma opção), mas como um operando ("argumento de nome de arquivo").
Com relação à sua última pergunta:
Para proteger o conteúdo de uma variável contra ser interpretado como um conjunto de opções ao usá-lo como
utility "$variable"
use
utility -- "$variable"
Se o utilitário for cat , sed , awk , paste , sort e possivelmente alguns outros (ou GNU touch ) e $variable será - , isso ainda fará com que o utilitário faça seu processamento especial, pois, como dito acima, - não é uma opção. Em vez disso, faça provisões para que os nomes dos arquivos, se eles começarem com ou forem iguais a - , sejam precedidos por um caminho, por exemplo, ./ para arquivos no diretório de trabalho atual.
Um bom hábito é usar
for filename in ./*; do
em vez de
for filename in *; do
por exemplo.