If the following example, which sets the IFS
environment variable to a line feed character...
IFS=$'\n'
- What does the dollar sign mean exactly?
- What does it do in this specific case?
- Where can I read more on this specific usage (Google doesn't allow special characters in searches and I don't know what to look for otherwise)?
I know what the IFS
environment variable is, and what the \n
character is (line feed), but why not just use the following form:
IFS="\n"
(which does not work)?
For example, if I want to loop through every line of a file and want to use a for loop, I could do this:
for line in (< /path/to/file); do
echo "Line: $line"
done
However, this won't work right unless IFS
is set to a line feed character. To get it to work, I'd have to do this:
OLDIFS=$IFS
IFS=$'\n'
for line in (< /path/to/file); do
echo "Line: $line"
done
IFS=$OLDIFS
Note: I don't need another way for doing the same thing, I know many other already... I'm only curious about that $'\n'
and wondered if anyone could give me an explanation on it.
Normally
bash
doesn't interpret escape sequences in string literals. So if you write\n
or"\n"
or'\n'
, that's not a linebreak - it's the lettern
(in the first case) or a backslash followed by the lettern
(in the other two cases).$'somestring'
is a syntax for string literals with escape sequences. So unlike'\n'
,$'\n'
actually is a linebreak.ANSI C-quoted strings is a key point. Thanks to @mklement0 .
You can test ANSI C-quoted strings with command od.
Outputs:
You can know the meaning clearly by the outputs.
Re recovering the default IFS- this
OLDIFS=$IFS
is not necessary. Run new IFS in subshell to avoid overriding the default IFS:Besides I don't really believe you recover the old IFS fully. You should double quote it to avoid line breaking such as
OLDIFS="$IFS"
.Just to give the construct its official name: strings of the form
$'...'
are called ANSI C-quoted strings.That is, as in [ANSI] C strings, backlash escape sequences are recognized and expanded to their literal equivalent (see below for the complete list of supported escape sequences).
After this expansion,
$'...'
strings behave the same way as'...'
strings - i.e., they're treated as literals NOT subject to any [further] shell expansions.For instance,
$'\n'
expands to a literal newline character - which is something a regular bash string literal (whether'...'
or"..."
) cannot do.[1]Another interesting feature is that ANSI C-quoted strings can escape
'
(single quotes) as\'
, which,'...'
(regular single-quoted strings) cannot:List of supported escape sequences:
[1] You can, however, embed actual newlines in '...' and "..." strings; i.e., you can define strings that span multiple lines.
From http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html:
I guess it's forcing the script to escape the line feed to the proper ANSI-C standard.
It's like retrieving the value from a variable:
are different, so the dollar sign basically evaluates the content.