How to `touch` and `cat` file named `-` [duplicate]

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
4
down vote

favorite













This question already has an answer here:



  • How do I delete a file whose name begins with “-” (hyphen a.k.a. dash or minus)?

    10 answers



How do I use GNU touch to update a file called -?



How do I use GNU cat to display a file called -?




I'm running:



% cat --version | head -n1
cat (GNU coreutils) 8.29
% touch --version | head -n1
touch (GNU coreutils) 8.29


Firstly, touch:



% touch -
% ls -l
total 0
% touch -- -
% ls -l -- -
ls: cannot access '-': No such file or directory


Ok, I'll give up on creating a file with touch. Let's create it with date instead:



% date > -
% ls -l -
-rw-r--r-- 1 ravi ravi 29 Sep 8 19:54 -
%


Now, let's try to cat it:



% cat -
% # I pressed ^D
% cat -- -
% # Same again - I pressed ^D


I know I can work around with:



% > -


and



% cat < -


But why don't these GNU utils support the convention that -- means that everything following is treated as a non-option?



How do I use these tools in the general case, for example I have a variable with the contents -?










share|improve this question















marked as duplicate by Barmar, Jeff Schaller, αғsнιη, Thomas, thrig Sep 8 at 14:47


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • @Barmar This is a more specific case where the filename is -. A lone - is not an option, so the issue is different from the issues in the questions that you have proposed as duplicates.
    – Kusalananda
    Sep 8 at 14:04










  • @Kusalananda A lone - is going to be treated as an invalid option or a placeholder for stdin or stdout. In any case, the solution is the same.
    – Barmar
    Sep 8 at 14:05










  • @Barmar Ok, but - is not an invalid option.
    – Kusalananda
    Sep 8 at 14:10










  • @Kusalananda If it's not treated as a synonym for stdin/stdout (as touch and cat do), and it's not a filename, and it's not an actual option, what else could it be? But this is immaterial, my point is that you use the same solution to deal with any filename beginning with -, it doesn't matter why it doesn't work normally.
    – Barmar
    Sep 8 at 14:14










  • Forget off the top of my head, but ti was covered in this "game" that teaches you escaping stuff, etc. Really like this series they have for learning a higher level of command line use... and I've been using Linux for 20 years... overthewire.org/wargames/bandit/bandit0.html
    – ivanivan
    Sep 8 at 14:45














up vote
4
down vote

favorite













This question already has an answer here:



  • How do I delete a file whose name begins with “-” (hyphen a.k.a. dash or minus)?

    10 answers



How do I use GNU touch to update a file called -?



How do I use GNU cat to display a file called -?




I'm running:



% cat --version | head -n1
cat (GNU coreutils) 8.29
% touch --version | head -n1
touch (GNU coreutils) 8.29


Firstly, touch:



% touch -
% ls -l
total 0
% touch -- -
% ls -l -- -
ls: cannot access '-': No such file or directory


Ok, I'll give up on creating a file with touch. Let's create it with date instead:



% date > -
% ls -l -
-rw-r--r-- 1 ravi ravi 29 Sep 8 19:54 -
%


Now, let's try to cat it:



% cat -
% # I pressed ^D
% cat -- -
% # Same again - I pressed ^D


I know I can work around with:



% > -


and



% cat < -


But why don't these GNU utils support the convention that -- means that everything following is treated as a non-option?



How do I use these tools in the general case, for example I have a variable with the contents -?










share|improve this question















marked as duplicate by Barmar, Jeff Schaller, αғsнιη, Thomas, thrig Sep 8 at 14:47


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • @Barmar This is a more specific case where the filename is -. A lone - is not an option, so the issue is different from the issues in the questions that you have proposed as duplicates.
    – Kusalananda
    Sep 8 at 14:04










  • @Kusalananda A lone - is going to be treated as an invalid option or a placeholder for stdin or stdout. In any case, the solution is the same.
    – Barmar
    Sep 8 at 14:05










  • @Barmar Ok, but - is not an invalid option.
    – Kusalananda
    Sep 8 at 14:10










  • @Kusalananda If it's not treated as a synonym for stdin/stdout (as touch and cat do), and it's not a filename, and it's not an actual option, what else could it be? But this is immaterial, my point is that you use the same solution to deal with any filename beginning with -, it doesn't matter why it doesn't work normally.
    – Barmar
    Sep 8 at 14:14










  • Forget off the top of my head, but ti was covered in this "game" that teaches you escaping stuff, etc. Really like this series they have for learning a higher level of command line use... and I've been using Linux for 20 years... overthewire.org/wargames/bandit/bandit0.html
    – ivanivan
    Sep 8 at 14:45












up vote
4
down vote

favorite









up vote
4
down vote

favorite












This question already has an answer here:



  • How do I delete a file whose name begins with “-” (hyphen a.k.a. dash or minus)?

    10 answers



How do I use GNU touch to update a file called -?



How do I use GNU cat to display a file called -?




I'm running:



% cat --version | head -n1
cat (GNU coreutils) 8.29
% touch --version | head -n1
touch (GNU coreutils) 8.29


Firstly, touch:



% touch -
% ls -l
total 0
% touch -- -
% ls -l -- -
ls: cannot access '-': No such file or directory


Ok, I'll give up on creating a file with touch. Let's create it with date instead:



% date > -
% ls -l -
-rw-r--r-- 1 ravi ravi 29 Sep 8 19:54 -
%


Now, let's try to cat it:



% cat -
% # I pressed ^D
% cat -- -
% # Same again - I pressed ^D


I know I can work around with:



% > -


and



% cat < -


But why don't these GNU utils support the convention that -- means that everything following is treated as a non-option?



How do I use these tools in the general case, for example I have a variable with the contents -?










share|improve this question
















This question already has an answer here:



  • How do I delete a file whose name begins with “-” (hyphen a.k.a. dash or minus)?

    10 answers



How do I use GNU touch to update a file called -?



How do I use GNU cat to display a file called -?




I'm running:



% cat --version | head -n1
cat (GNU coreutils) 8.29
% touch --version | head -n1
touch (GNU coreutils) 8.29


Firstly, touch:



% touch -
% ls -l
total 0
% touch -- -
% ls -l -- -
ls: cannot access '-': No such file or directory


Ok, I'll give up on creating a file with touch. Let's create it with date instead:



% date > -
% ls -l -
-rw-r--r-- 1 ravi ravi 29 Sep 8 19:54 -
%


Now, let's try to cat it:



% cat -
% # I pressed ^D
% cat -- -
% # Same again - I pressed ^D


I know I can work around with:



% > -


and



% cat < -


But why don't these GNU utils support the convention that -- means that everything following is treated as a non-option?



How do I use these tools in the general case, for example I have a variable with the contents -?





This question already has an answer here:



  • How do I delete a file whose name begins with “-” (hyphen a.k.a. dash or minus)?

    10 answers







linux cat touch






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 8 at 13:32

























asked Sep 8 at 13:17









Tom Hale

5,94622776




5,94622776




marked as duplicate by Barmar, Jeff Schaller, αғsнιη, Thomas, thrig Sep 8 at 14:47


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






marked as duplicate by Barmar, Jeff Schaller, αғsнιη, Thomas, thrig Sep 8 at 14:47


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.













  • @Barmar This is a more specific case where the filename is -. A lone - is not an option, so the issue is different from the issues in the questions that you have proposed as duplicates.
    – Kusalananda
    Sep 8 at 14:04










  • @Kusalananda A lone - is going to be treated as an invalid option or a placeholder for stdin or stdout. In any case, the solution is the same.
    – Barmar
    Sep 8 at 14:05










  • @Barmar Ok, but - is not an invalid option.
    – Kusalananda
    Sep 8 at 14:10










  • @Kusalananda If it's not treated as a synonym for stdin/stdout (as touch and cat do), and it's not a filename, and it's not an actual option, what else could it be? But this is immaterial, my point is that you use the same solution to deal with any filename beginning with -, it doesn't matter why it doesn't work normally.
    – Barmar
    Sep 8 at 14:14










  • Forget off the top of my head, but ti was covered in this "game" that teaches you escaping stuff, etc. Really like this series they have for learning a higher level of command line use... and I've been using Linux for 20 years... overthewire.org/wargames/bandit/bandit0.html
    – ivanivan
    Sep 8 at 14:45
















  • @Barmar This is a more specific case where the filename is -. A lone - is not an option, so the issue is different from the issues in the questions that you have proposed as duplicates.
    – Kusalananda
    Sep 8 at 14:04










  • @Kusalananda A lone - is going to be treated as an invalid option or a placeholder for stdin or stdout. In any case, the solution is the same.
    – Barmar
    Sep 8 at 14:05










  • @Barmar Ok, but - is not an invalid option.
    – Kusalananda
    Sep 8 at 14:10










  • @Kusalananda If it's not treated as a synonym for stdin/stdout (as touch and cat do), and it's not a filename, and it's not an actual option, what else could it be? But this is immaterial, my point is that you use the same solution to deal with any filename beginning with -, it doesn't matter why it doesn't work normally.
    – Barmar
    Sep 8 at 14:14










  • Forget off the top of my head, but ti was covered in this "game" that teaches you escaping stuff, etc. Really like this series they have for learning a higher level of command line use... and I've been using Linux for 20 years... overthewire.org/wargames/bandit/bandit0.html
    – ivanivan
    Sep 8 at 14:45















@Barmar This is a more specific case where the filename is -. A lone - is not an option, so the issue is different from the issues in the questions that you have proposed as duplicates.
– Kusalananda
Sep 8 at 14:04




@Barmar This is a more specific case where the filename is -. A lone - is not an option, so the issue is different from the issues in the questions that you have proposed as duplicates.
– Kusalananda
Sep 8 at 14:04












@Kusalananda A lone - is going to be treated as an invalid option or a placeholder for stdin or stdout. In any case, the solution is the same.
– Barmar
Sep 8 at 14:05




@Kusalananda A lone - is going to be treated as an invalid option or a placeholder for stdin or stdout. In any case, the solution is the same.
– Barmar
Sep 8 at 14:05












@Barmar Ok, but - is not an invalid option.
– Kusalananda
Sep 8 at 14:10




@Barmar Ok, but - is not an invalid option.
– Kusalananda
Sep 8 at 14:10












@Kusalananda If it's not treated as a synonym for stdin/stdout (as touch and cat do), and it's not a filename, and it's not an actual option, what else could it be? But this is immaterial, my point is that you use the same solution to deal with any filename beginning with -, it doesn't matter why it doesn't work normally.
– Barmar
Sep 8 at 14:14




@Kusalananda If it's not treated as a synonym for stdin/stdout (as touch and cat do), and it's not a filename, and it's not an actual option, what else could it be? But this is immaterial, my point is that you use the same solution to deal with any filename beginning with -, it doesn't matter why it doesn't work normally.
– Barmar
Sep 8 at 14:14












Forget off the top of my head, but ti was covered in this "game" that teaches you escaping stuff, etc. Really like this series they have for learning a higher level of command line use... and I've been using Linux for 20 years... overthewire.org/wargames/bandit/bandit0.html
– ivanivan
Sep 8 at 14:45




Forget off the top of my head, but ti was covered in this "game" that teaches you escaping stuff, etc. Really like this series they have for learning a higher level of command line use... and I've been using Linux for 20 years... overthewire.org/wargames/bandit/bandit0.html
– ivanivan
Sep 8 at 14:45










1 Answer
1






active

oldest

votes

















up vote
10
down vote



accepted










Use an explicit path to the file:



touch ./-
cat ./-


GNU touch treats a file operand of - specially:




A FILE argument string of - is handled specially and causes touch to
change the times of the file associated with standard output.




For cat, the POSIX standard specifies that a file operand - should be interpreted as a request to read from standard input.



The double-dash convention is still in effect, but it's not for signalling the end of arguments but the end of options. In neither of these cases would - be taken as an option (a lone - can not be an option) but as an operand ("file name argument").




Regarding your last question:



To protect the contents of a variable against being interpreted as a set of options when using it as



utility "$variable"


use



utility -- "$variable"


Note that if the utility is cat, sed, awk, paste, sort and possibly a few others (or GNU touch), and $variable is -, this will still cause the utility to do its special processing since, as said above, - is not an option. Instead, make provisions so that filenames, if they may start with or are equal to -, are preceded by a path, for example ./ for files in the current working directory.



A good habit is to use



for filename in ./*; do


rather than



for filename in *; do


for example.






share|improve this answer






















  • It seems the way for absolute belts and braces would be to do cat "$(readlink -f "$file")"
    – Tom Hale
    Sep 8 at 13:35











  • What about the touch case though?
    – Tom Hale
    Sep 8 at 13:36










  • @TomHale no. readlink -f is not portable. What about the touch case?
    – Kusalananda
    Sep 8 at 13:38










  • So [ "$file" = - ] && file=./- is needed before each invocation of GNU cat and touch for the truly paranoid? Any nicer ways?
    – Tom Hale
    Sep 8 at 13:40







  • 4




    @TomHale If you're looping over files in a directory, make a habit of using for file in ./* or similar, instead of for file in *.
    – Kusalananda
    Sep 8 at 13:43


















1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
10
down vote



accepted










Use an explicit path to the file:



touch ./-
cat ./-


GNU touch treats a file operand of - specially:




A FILE argument string of - is handled specially and causes touch to
change the times of the file associated with standard output.




For cat, the POSIX standard specifies that a file operand - should be interpreted as a request to read from standard input.



The double-dash convention is still in effect, but it's not for signalling the end of arguments but the end of options. In neither of these cases would - be taken as an option (a lone - can not be an option) but as an operand ("file name argument").




Regarding your last question:



To protect the contents of a variable against being interpreted as a set of options when using it as



utility "$variable"


use



utility -- "$variable"


Note that if the utility is cat, sed, awk, paste, sort and possibly a few others (or GNU touch), and $variable is -, this will still cause the utility to do its special processing since, as said above, - is not an option. Instead, make provisions so that filenames, if they may start with or are equal to -, are preceded by a path, for example ./ for files in the current working directory.



A good habit is to use



for filename in ./*; do


rather than



for filename in *; do


for example.






share|improve this answer






















  • It seems the way for absolute belts and braces would be to do cat "$(readlink -f "$file")"
    – Tom Hale
    Sep 8 at 13:35











  • What about the touch case though?
    – Tom Hale
    Sep 8 at 13:36










  • @TomHale no. readlink -f is not portable. What about the touch case?
    – Kusalananda
    Sep 8 at 13:38










  • So [ "$file" = - ] && file=./- is needed before each invocation of GNU cat and touch for the truly paranoid? Any nicer ways?
    – Tom Hale
    Sep 8 at 13:40







  • 4




    @TomHale If you're looping over files in a directory, make a habit of using for file in ./* or similar, instead of for file in *.
    – Kusalananda
    Sep 8 at 13:43















up vote
10
down vote



accepted










Use an explicit path to the file:



touch ./-
cat ./-


GNU touch treats a file operand of - specially:




A FILE argument string of - is handled specially and causes touch to
change the times of the file associated with standard output.




For cat, the POSIX standard specifies that a file operand - should be interpreted as a request to read from standard input.



The double-dash convention is still in effect, but it's not for signalling the end of arguments but the end of options. In neither of these cases would - be taken as an option (a lone - can not be an option) but as an operand ("file name argument").




Regarding your last question:



To protect the contents of a variable against being interpreted as a set of options when using it as



utility "$variable"


use



utility -- "$variable"


Note that if the utility is cat, sed, awk, paste, sort and possibly a few others (or GNU touch), and $variable is -, this will still cause the utility to do its special processing since, as said above, - is not an option. Instead, make provisions so that filenames, if they may start with or are equal to -, are preceded by a path, for example ./ for files in the current working directory.



A good habit is to use



for filename in ./*; do


rather than



for filename in *; do


for example.






share|improve this answer






















  • It seems the way for absolute belts and braces would be to do cat "$(readlink -f "$file")"
    – Tom Hale
    Sep 8 at 13:35











  • What about the touch case though?
    – Tom Hale
    Sep 8 at 13:36










  • @TomHale no. readlink -f is not portable. What about the touch case?
    – Kusalananda
    Sep 8 at 13:38










  • So [ "$file" = - ] && file=./- is needed before each invocation of GNU cat and touch for the truly paranoid? Any nicer ways?
    – Tom Hale
    Sep 8 at 13:40







  • 4




    @TomHale If you're looping over files in a directory, make a habit of using for file in ./* or similar, instead of for file in *.
    – Kusalananda
    Sep 8 at 13:43













up vote
10
down vote



accepted







up vote
10
down vote



accepted






Use an explicit path to the file:



touch ./-
cat ./-


GNU touch treats a file operand of - specially:




A FILE argument string of - is handled specially and causes touch to
change the times of the file associated with standard output.




For cat, the POSIX standard specifies that a file operand - should be interpreted as a request to read from standard input.



The double-dash convention is still in effect, but it's not for signalling the end of arguments but the end of options. In neither of these cases would - be taken as an option (a lone - can not be an option) but as an operand ("file name argument").




Regarding your last question:



To protect the contents of a variable against being interpreted as a set of options when using it as



utility "$variable"


use



utility -- "$variable"


Note that if the utility is cat, sed, awk, paste, sort and possibly a few others (or GNU touch), and $variable is -, this will still cause the utility to do its special processing since, as said above, - is not an option. Instead, make provisions so that filenames, if they may start with or are equal to -, are preceded by a path, for example ./ for files in the current working directory.



A good habit is to use



for filename in ./*; do


rather than



for filename in *; do


for example.






share|improve this answer














Use an explicit path to the file:



touch ./-
cat ./-


GNU touch treats a file operand of - specially:




A FILE argument string of - is handled specially and causes touch to
change the times of the file associated with standard output.




For cat, the POSIX standard specifies that a file operand - should be interpreted as a request to read from standard input.



The double-dash convention is still in effect, but it's not for signalling the end of arguments but the end of options. In neither of these cases would - be taken as an option (a lone - can not be an option) but as an operand ("file name argument").




Regarding your last question:



To protect the contents of a variable against being interpreted as a set of options when using it as



utility "$variable"


use



utility -- "$variable"


Note that if the utility is cat, sed, awk, paste, sort and possibly a few others (or GNU touch), and $variable is -, this will still cause the utility to do its special processing since, as said above, - is not an option. Instead, make provisions so that filenames, if they may start with or are equal to -, are preceded by a path, for example ./ for files in the current working directory.



A good habit is to use



for filename in ./*; do


rather than



for filename in *; do


for example.







share|improve this answer














share|improve this answer



share|improve this answer








edited Sep 8 at 15:20

























answered Sep 8 at 13:24









Kusalananda

107k14209331




107k14209331











  • It seems the way for absolute belts and braces would be to do cat "$(readlink -f "$file")"
    – Tom Hale
    Sep 8 at 13:35











  • What about the touch case though?
    – Tom Hale
    Sep 8 at 13:36










  • @TomHale no. readlink -f is not portable. What about the touch case?
    – Kusalananda
    Sep 8 at 13:38










  • So [ "$file" = - ] && file=./- is needed before each invocation of GNU cat and touch for the truly paranoid? Any nicer ways?
    – Tom Hale
    Sep 8 at 13:40







  • 4




    @TomHale If you're looping over files in a directory, make a habit of using for file in ./* or similar, instead of for file in *.
    – Kusalananda
    Sep 8 at 13:43

















  • It seems the way for absolute belts and braces would be to do cat "$(readlink -f "$file")"
    – Tom Hale
    Sep 8 at 13:35











  • What about the touch case though?
    – Tom Hale
    Sep 8 at 13:36










  • @TomHale no. readlink -f is not portable. What about the touch case?
    – Kusalananda
    Sep 8 at 13:38










  • So [ "$file" = - ] && file=./- is needed before each invocation of GNU cat and touch for the truly paranoid? Any nicer ways?
    – Tom Hale
    Sep 8 at 13:40







  • 4




    @TomHale If you're looping over files in a directory, make a habit of using for file in ./* or similar, instead of for file in *.
    – Kusalananda
    Sep 8 at 13:43
















It seems the way for absolute belts and braces would be to do cat "$(readlink -f "$file")"
– Tom Hale
Sep 8 at 13:35





It seems the way for absolute belts and braces would be to do cat "$(readlink -f "$file")"
– Tom Hale
Sep 8 at 13:35













What about the touch case though?
– Tom Hale
Sep 8 at 13:36




What about the touch case though?
– Tom Hale
Sep 8 at 13:36












@TomHale no. readlink -f is not portable. What about the touch case?
– Kusalananda
Sep 8 at 13:38




@TomHale no. readlink -f is not portable. What about the touch case?
– Kusalananda
Sep 8 at 13:38












So [ "$file" = - ] && file=./- is needed before each invocation of GNU cat and touch for the truly paranoid? Any nicer ways?
– Tom Hale
Sep 8 at 13:40





So [ "$file" = - ] && file=./- is needed before each invocation of GNU cat and touch for the truly paranoid? Any nicer ways?
– Tom Hale
Sep 8 at 13:40





4




4




@TomHale If you're looping over files in a directory, make a habit of using for file in ./* or similar, instead of for file in *.
– Kusalananda
Sep 8 at 13:43





@TomHale If you're looping over files in a directory, make a habit of using for file in ./* or similar, instead of for file in *.
– Kusalananda
Sep 8 at 13:43



Popular posts from this blog

How to check contact read email or not when send email to Individual?

Bahrain

Postfix configuration issue with fips on centos 7; mailgun relay