What is the meaning of read -r?
There is no stand-alone read
command: instead, it is a shell built-in, and as such is documented in the man page for bash
:
read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
︙
-r
Backslash does not act as an escape character. The backslash is considered to be part of the line. In particular, a backslash-newline pair may not be used as a line continuation.
So, to summarize, read
normally allows long lines to be broken using a trailing backslash character, and normally reconstructs such lines. This slightly surprising behavior can be deactivated using -r
.
The -r
option prevents backslash escapes from being interpreted. Here's an example:
Assume there's a file with this content:
ngRTM6hNqgziZcqCcEJN7bHAP9a1GeMs\
Ni3EAX1qvogWpRIPE3oagJL6nwl\QQW9y
bjJHyaVBrUcyZOY5U4h9QHnpEPqg\\\\\\\\\Q9Fk
iNOvAyBTAcN5n1uwR4GvRfAGUbPWiXax\n
cqGPPStH3gaWolrfVAlMtoWiSuLa7GzQ\n\n\n
EnO04N1nEkpWbfXRxrtYNqCZDpF\trQIXS
$ while read line; do echo $line; done < tempfile
ngRTM6hNqgziZcqCcEJN7bHAP9a1GeMsNi3EAX1qvogWpRIPE3oagJL6nwlQQW9y
bjJHyaVBrUcyZOY5U4h9QHnpEPqg\\\\Q9Fk
iNOvAyBTAcN5n1uwR4GvRfAGUbPWiXaxn
cqGPPStH3gaWolrfVAlMtoWiSuLa7GzQnnn
EnO04N1nEkpWbfXRxrtYNqCZDpFtrQIXS
$ while read -r line; do echo $line; done < tempfile
ngRTM6hNqgziZcqCcEJN7bHAP9a1GeMs\
Ni3EAX1qvogWpRIPE3oagJL6nwl\QQW9y
bjJHyaVBrUcyZOY5U4h9QHnpEPqg\\\\\\\\\Q9Fk
iNOvAyBTAcN5n1uwR4GvRfAGUbPWiXax\n
cqGPPStH3gaWolrfVAlMtoWiSuLa7GzQ\n\n\n
EnO04N1nEkpWbfXRxrtYNqCZDpF\trQIXS
The Bash man page's section about read
states that, by default...
The backslash character (
\
) may be used to remove any special meaning for the next character read and for line continuation.
but, if you pass -r
, then
Backslash does not act as an escape character. The backslash is considered to be part of the line. In particular, a backslash-newline pair may not then be used as a line continuation.
A little thought suggests that the only possible "special meaning" they could be talking about is the character serving as a delimiter. And sure enough, without -r
, you can backslash-escape a delimiter or a newline, but with -r
, you can't, and backslashes just get interpreted as literal backslashes:
$ read -d 'x' var1 <<< 'There was once \
a curious Uni\x user.xHe did a little test.'
$ echo "$var1"
There was once a curious Unix user.
$ read -d 'x' -r var2 <<< 'There was once \
a curious Uni\x user.xHe did a little test.'
$ echo "$var2"
There was once \
a curious Uni\