18

How can I read a dash file from the terminal other than delimiting it with ./

For example to read a - file we can read it by

cat ./-file_name

Q: Is there an alternative way to achieve the same thing?

2
  • 4
    the recommended way is actually to use ./ prefix. It's the most portable (cf the usenet era's Unix FAQ) Mar 10, 2015 at 16:14
  • find . -name "-filename" | xargs cat will send ./-filename through the pipe. For your (simplified?) case a mistake, but it might help in large directories / scripts.
    – Walter A
    Mar 10, 2015 at 21:21

3 Answers 3

29

Use double -- to mark end of options:

cat -- -<FILENAME>

Other programs such as touch, rm or git checkout also follow this convention:

$ touch -- -file
$ ll
total 0
-rw-r--r-- 1 ja ja 0 Mar 10 13:13 -file
$ echo hi! >> -file
$ cat -- -file
hi!
$ rm -- -file
$ echo $?
0

WARNING: It's good practice to always use -- after rm in scripts. An attacker could place --rf file in a directory and rm * would take it as run parameters. See this:

$ touch A
$ touch B
$ mkdir dir
$ touch dir/C
$ touch -- -rf
$ rm *
$ ll
total 0
-rw-r--r-- 1 ja ja 0 Mar 10 13:21 -rf

Oops, this is not we meant, we didn't want to remove directories. We should have used --:

$ touch A
$ touch B
$ mkdir dir
$ touch dir/C
$ touch -- -rf
$ rm -- *
rm: cannot remove `dir': Is a directory
$ ll
total 4.0K
drwxr-xr-x 2 ja ja 4.0K Mar 10 13:22 dir
9
  • 4
    You can't count on every program implementing --: many do but not all. Mar 10, 2015 at 13:44
  • 2
    Really? I didn't say that all programs implement --, I said showed some that do. Mar 10, 2015 at 13:47
  • 1
    @vidhan: am not aware of any other option. Mar 10, 2015 at 14:50
  • 1
    @vidhan you can also complicate your life for no reason and do something like find . -name '-file_name' -exec cat {} \; but there really isn't much point to it.
    – terdon
    Mar 10, 2015 at 17:50
  • 3
    This doesn't work if the file is named - and nothing else? This came up in the wargame: overthewire.org/wargames/bandit/bandit2.html
    – ThisClark
    May 12, 2017 at 17:29
18

For commands which get input from stdin, you can use redirection:

cat <-file_name
1
  • ya this one works :) is so I got 3 ways to read them one by using ./ other by using -- and another by using <, any more ways to do the same thing ??
    – vidhan
    Mar 10, 2015 at 15:25
2

Alternatives become weird:

dd if=-x 2>/dev/null

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .