16

I have no idea what created this file - I guess a terrible shell script.

It is called '.env'$'\r'

I have tried various versions of rm, and the technique of opening the direcory with vim ./, selecting the file, and Shift-D to delete.
This didn't work, failing with a

**warning** (netrw) delete(/root/squawker/.env) failed!
NetrwMessage [RO]
"NetrwMessage"  --No lines in buffer--

How can I delete this pesky file?

This is on Ubuntu 20.04

  • 5
    I expect the cause is a shell script that somehow acquired DOS line endings - check your script files for trailing carriage returns. Examining the content of the file might give you a clue as to where it came from. – Toby Speight May 21 '22 at 07:53

4 Answers4

23

On recent-ish Linux systems (with GNU tools as in most desktop distributions), ls prints names with weird characters using the shell's quoting syntax. If that '.env'$'\r' is what ls gives, the name of the file is .env<CR>, where <CR> is the carriage-return character. You could get that if you had a shell script with Windows line-endings that ran e.g. whatever > .env.

The good thing here is that the output of ls there is directly usable as input to the shell. Well, to Bash, ksh, and zsh at least, not a standard POSIX sh, like Debian/Ubuntu's /bin/sh, Dash.

So try with just

rm -f '.env'$'\r'

Of course rm -f .env? should also work to remove anything named .env plus any one character.

Now, of course it's also possible that the filename is literally that, what with the single quotes and backslashes. But that's more difficult to achieve by accident. Even so, rm -f *.env* should work to delete anything with .env in the name.

ilkkachu
  • 133,243
  • 15
  • 236
  • 397
  • 3
    `$'.env\r'` would be a clearer / more readable way to write it, with the whole thing inside C-escape-expanding quotes. Oh, but that is how `ls --quoting-style=shell-escape .env*` prints it, unfortunately, if I `touch` that filename first. This looks like a good use-case for `rm -i .env?` or `.env*` as another answer points out. – Peter Cordes May 21 '22 at 03:46
  • 2
    Note that it's a behaviour of the GNU implementation of `ls`, it has nothing to do with Linux. – Stéphane Chazelas May 21 '22 at 13:56
23

If using GNU find, then you can delete it by the inode.

ls -lid -- .env*

The number in the first column is the inode. Note what it is for the file that you actually want should others with the string env in the filename exist.

find . -inum <inode> -exec rm -f {} \;

Replace <inode> with the actual inode number. You can remove the -exec part so that you know that it is returning the file that you want before deleting it.

You can also use:

find . -inum <inode> -delete

I sometimes use the -exec bit out of habit but either one works.

Nasir Riley
  • 10,665
  • 2
  • 18
  • 27
13

Ask the shell to wildcard the tricky part of the name, and ask rm to remember it for you so you don't need to type it.

$ touch '.env'$'\r'
$ ls -l .env*
-rw-rw-r-- 1 paul paul 0 May 20 16:51 '.env'$'\r'
$ rm -i .env*
rm: remove regular empty file '.env'$'\r'? y
Paul_Pedant
  • 8,228
  • 2
  • 18
  • 26
11

A quick-and-dirty way to select pesky filenames is to use the autocompletion feature of the shell.

Type rm , then hit the TAB key until the file to remove is printed on screen.

dr_
  • 28,763
  • 21
  • 89
  • 133
  • 3
    Which shell, configured how? – Mark May 20 '22 at 22:47
  • 2
    zsh would rotate between the matching ones, but I don't think Bash can do that. So, `.env` would work in Bash if there's only that one filename starting like that. But if e.g. `.env` also exists, then the completion doesn't really help. – ilkkachu May 21 '22 at 08:36
  • With BASH, if you press TAB twice in a row, it shows all the completions, but it doesn't escape them correctly (I tried with a newline in the filename) – CSM May 21 '22 at 14:08
  • @CSM, it does autofill correctly, though, if it's the only matching filename. But you can't copypaste from the listing. – ilkkachu May 21 '22 at 14:38
  • For bash use `"'.en` and then TAB. The file name should be completed correctly. – Thorbjørn Ravn Andersen May 21 '22 at 17:51
  • @ThorbjørnRavnAndersen: Most likely the question title is misleading, and the OP copied the output of GNU `ls --quoting-style=shell-escape`. This and other answers and comments are assuming that, not that the question title is literally true. (That's what I assumed, though, when seeing it in HNQ before clicking. But much more likely to be `.env` with a stray carriage return). I think your suggestion is for `'.env'$'\r'` as the literal filename, starting with a literal single-quote, and you're enclosing that in double-quotes for the shell. – Peter Cordes May 22 '22 at 02:05
  • @PeterCordes sounds right. Thanks! – Thorbjørn Ravn Andersen May 22 '22 at 04:43