7

I'm confused by this experiment (in Bash):

$ mkdir 'foo\n'
$ find . -print0 | od -c
0000000   .  \0   .   /   f   o   o   \   n  \0
0000012

As you can see, "find" is correctly delimiting the output with null characters, but it escapes the newline in the directory name as "foo\n" with a backslash "n". Why is it doing this? I told it "-print0" which says "This allows file names that contain newlines ... to be correctly interpreted by programs that process the find output." The escaping should not be necessary, since "\0" is the delimiter, not "\n".

closed as off-topic by Michael Homer, mosvy, Jesse_b, Archemar, jimmij Feb 25 at 13:39

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions describing a problem that can't be reproduced and seemingly went away on its own (or went away when a typo was fixed) are off-topic as they are unlikely to help future readers." – Michael Homer, mosvy, Jesse_b, Archemar, jimmij
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 14
    You made a directory called literally foo\n, with a backslash in its name. – Michael Homer Feb 23 at 6:36
  • 7
    Soo ... embarrassing .... but learned something from the answers, thank you all. – Metamorphic Feb 23 at 6:50
  • If you did an ls you would have seen that. – Bakuriu Feb 23 at 10:32
  • @Bakuriu, no because ls prints exactly what I passed to mkdir, 'foo\n'... – Metamorphic Feb 23 at 10:42
  • There is no Neulinge in your filename, ‚\n‘ is a literal 2 char string – eckes Feb 23 at 15:42
20

The problem is not in find, but in how you're creating this directory. The single quoted string 'foo\n' is actually a 5-character string, of which the last two are a backslash and a lowercase "n".

Double-quoting it doesn't help either, since double-quoted strings in shell use backslash as an escape character, but don't really interpret any of the C-style backslash sequences.

In a shell such as bash or zsh, etc. (but not dash from Debian/Ubuntu), you can use $'...', which interprets those sequences:

$ mkdir $'foo\n'

(See bash's documentation for this feature, called "ANSI C Quoting").

Another option, that should work in any shell compatible with bourne shell is to insert an actual newline:

$ mkdir 'foo
'

That's an actual Return at the end of the first line, only closing the single quote on the second line.

6

Let's make a directory named foo plus a newline:

$ mkdir $'foo\n'

Now, let's use find:

$ find .  -print0 | od -c
0000000   .  \0   .   /   f   o   o  \n  \0
0000011

\n is not escaped.

The issue is that mkdir 'foo\n' is the name is interpreted as foo followed by \ followed by n. We can verify that with:

$ printf '%s' 'foo\n' | od -c
0000000   f   o   o   \   n
0000005
  • 1
    I appreciate showing the verification part! – pabouk Feb 23 at 21:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.