Use cases for cat without arguments
Table of contents
Use cases for cat without arguments
Today I was trying to recall a command-line trick I use all the time, where I paste some file names in the console, one file per line, and I delete all of them at once.
For some season, I totally forgot how to do that (no, it’s not that I’m getting old). I remembered that it involved running the cat command without arguments, but I kept mixing it up with some other tricks I use with cat.
So, after recalling the trick, I decided it’s time to write a new post and share all the cat-with-no-arguments tricks I know here, and totally never forget them again.
1) cat without arguments
If you give the cat command a file name, it will output it contents to the console.
But if you omit the filename, you can essentially provide the file yourself, from stdin, by typing in the console.
So, right away, cat without arguments is super useful because you can provide input to other commands via pipes from the command line, without having to create files or run other commands first.
$ cat | tr 'o' 'a'
Hello World # I typed Hello World, <enter>, <ctrl> + <D> (EOF)
Hella Warld # and I got Hella WarldBy the way, if you want to avoid printing each line, every time you press <enter> with the tr command, increase the output buffering of tr (I guess it’s line buffered by default) with stdbuf. For example:
$ cat | stdbuf -o 1024 tr 'o' 'a'
Hello # I typed Hello, <enter>, World, <enter>, !!!, <enter>, <ctrl> + <D> (EOF)
World
!!!
Hella # and I got the following
Warld
!!!2) xargs
The “trick” I was trying to recall, was that you have to use the xargs utility before the command you want to pipe the cat output to.
xargs transforms each line you provide from stdin, to an argument for the command you tell it to run.
$ cat | xargs ls -lha
# or cat | xargs rm
# but be careful with the rm.So, using the above, If I type:
one,<space>(line 1)two,<ctrl> + D(line 2)
It will try to run: ls -lha one two.
3) command substitution
Another use case is to put cat without arguments inside another shell feature, the command substitution. A reason to do that, is to pass to the command sensitive information, for example a password, and avoid leaking them in bash history:
$ curl -X POST -H 'Authorization: Basic $(cat)' 'https://example.org/'This way, I can provide my http token (and press ctrl + D after I’m done), and the shell history will only log the above command as is and not my token.
It works with multiple arguments too; in this case, you have to press ctrl + D one time for each command substitution.
4) process substitution
Process substitution basically treats some commands’ output as a file (this specific form, there’s another form but it’s less common). It gives you back a temporary file that you can use as argument to commands that expect a file.
In the following command, I examine the difference that the -a argument makes in the ls command, with the diff command, that expects 2 filenames:
$ diff <(ls -lha) <(ls -lh)Now, in the following example, you can copy paste two times to view the difference between the 2 texts you pasted:
$ (diff <(cat) <(cat))Note: The command above doesn’t work because the two cat commands compete for stdin and the output is not deterministic. Also, you have to run them in a sub-shell, in order to be grouped under the same parent id, otherwise it doesn’t work at all.
Although it doesn’t work, I learned something interesting from this section and you may too.
So, you’re better off using a code editor for diffing text and not command line tools. But if you must diff them in the command line, interactively, with copy and paste, you can do the following:
$ diff <(echo '1
2
3') <(echo '1
3
3')
2c2
< 2
---
> 3You write diff <(echo ', then paste the text, then write ') <(echo ', paste again, write ') and enter.
So, once again, I mixed some tricks. Process substitution is not the way to interactively compare texts from the terminal, got it.
And that’s it. I hope you learned something new, or at least got a refresher, like I did.