Skip to main content
added 43 characters in body
Source Link
Stéphane Chazelas
  • 584.8k
  • 96
  • 1.1k
  • 1.7k

That's because in <<< $line, bash doesversions prior to 4.4 did word splitting, (though not globbing) on $line as it'swhen not quoted there and then joinsjoined the resulting words with the space character (and putsput that in a temporary file followed by a newline character and makesmake that the stdin of cut).

$ a=a,b,,c bash-4.3 -c 'IFS=","; sed -n l <<< $a'
a b  c$

tab happens to be in the default value of $IFS:

$ a=$'a\tb'  bash-4.3 -c 'sed -n l <<< $a'
a b$

The solution with bash is to quote the variable.

$ a=$'a\tb' bash -c 'sed -n l <<< "$a"'
a\tb$

Note that it's the only shell that does that. zsh (where <<< comes from, inspired by the Unix portByron Rakitzis's implementation of rc), ksh93, mksh and yash which also support <<< don't do it.

When it comes to arrays, mksh, yash and zsh join on the first character of $IFS, bash and ksh93 on space.

$ mksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ yash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ ksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ bash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$

There's a difference between zsh/yash and mksh (version R52 at least) when $IFS is empty:

$ mksh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
12$

The behaviour is more consistent across shells when you use "${a[*]}" (except that mksh still has a bug when $IFS is empty).

In echo $line | ..., that's the usual split+glob operator in all Bourne-like shells but zsh (and the usual problems associated with echo).

That's because in <<< $line, bash does word splitting, (though not globbing) on $line as it's not quoted there and then joins the resulting words with the space character (and puts that in a temporary file followed by a newline character and makes that the stdin of cut).

$ a=a,b,,c bash -c 'IFS=","; sed -n l <<< $a'
a b  c$

tab happens to be in the default value of $IFS:

$ a=$'a\tb'  bash -c 'sed -n l <<< $a'
a b$

The solution with bash is to quote the variable.

$ a=$'a\tb' bash -c 'sed -n l <<< "$a"'
a\tb$

Note that it's the only shell that does that. zsh (where <<< comes from, inspired by the Unix port of rc), ksh93, mksh and yash which also support <<< don't do it.

When it comes to arrays, mksh, yash and zsh join on the first character of $IFS, bash and ksh93 on space.

$ mksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ yash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ ksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ bash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$

There's a difference between zsh/yash and mksh (version R52 at least) when $IFS is empty:

$ mksh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
12$

The behaviour is more consistent across shells when you use "${a[*]}" (except that mksh still has a bug when $IFS is empty).

In echo $line | ..., that's the usual split+glob operator in all Bourne-like shells but zsh (and the usual problems associated with echo).

That's because in <<< $line, bash versions prior to 4.4 did word splitting, (though not globbing) on $line when not quoted there and then joined the resulting words with the space character (and put that in a temporary file followed by a newline character and make that the stdin of cut).

$ a=a,b,,c bash-4.3 -c 'IFS=","; sed -n l <<< $a'
a b  c$

tab happens to be in the default value of $IFS:

$ a=$'a\tb'  bash-4.3 -c 'sed -n l <<< $a'
a b$

The solution with bash is to quote the variable.

$ a=$'a\tb' bash -c 'sed -n l <<< "$a"'
a\tb$

Note that it's the only shell that does that. zsh (where <<< comes from, inspired by Byron Rakitzis's implementation of rc), ksh93, mksh and yash which also support <<< don't do it.

When it comes to arrays, mksh, yash and zsh join on the first character of $IFS, bash and ksh93 on space.

$ mksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ yash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ ksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ bash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$

There's a difference between zsh/yash and mksh (version R52 at least) when $IFS is empty:

$ mksh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
12$

The behaviour is more consistent across shells when you use "${a[*]}" (except that mksh still has a bug when $IFS is empty).

In echo $line | ..., that's the usual split+glob operator in all Bourne-like shells but zsh (and the usual problems associated with echo).

added 75 characters in body
Source Link
Stéphane Chazelas
  • 584.8k
  • 96
  • 1.1k
  • 1.7k

That's because in <<< $line, bash does word splitting, (though not globbing) on $line as it's not quoted there and then joins the resulting words with the space character (and puts that in a temporary file followed by a newline character and makes that the stdin of cut).

$ a=a,b,,c bash -c 'IFS=","; sed -n l <<< $a'
a b  c$

tab happens to be in the default value of $IFS:

$ a=$'a\tb'  bash -c 'sed -n l <<< $a'
a b$

The solution with bash is to quote the variable.

$   a=$'a\tb' bash -c 'sed -n l <<< "$a"'
a\tb$

The solution with bash is to quote the variable.

Note that it's the only shell that does that. zsh (where <<< comes from, inspired by the Unix port of rc), ksh93, mksh and yash which also support <<< don't do it.

When it comes to arrays, mksh, yash and zsh join on the first character of $IFS, bash and ksh93 on space.

$ mksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ yash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ ksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ bash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$

There's a difference between zsh/yash and mksh (version R52 at least) when $IFS is empty:

$ mksh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
12$

The behaviour is more consistent across shells when you use "${a[*]}" (except that mksh still has a bug when $IFS is empty).

In echo $line | ..., that's the usual split+glob operator in all Bourne-like shells but zsh (and the usual problems associated with echo).

That's because bash does word splitting, (though not globbing) on $line as it's not quoted there and then joins the resulting words with the space character (and puts that in a temporary file followed by a newline character and makes that the stdin of cut).

$ a=a,b,,c bash -c 'IFS=","; sed -n l <<< $a'
a b  c$
$ a=$'a\tb'  bash -c 'sed -n l <<< $a'
a b$
$  a=$'a\tb' bash -c 'sed -n l <<< "$a"'
a\tb$

The solution with bash is to quote the variable.

Note that it's the only shell that does that. zsh (where <<< comes from, inspired by the Unix port of rc), ksh93, mksh and yash which also support <<< don't do it.

When it comes to arrays, mksh, yash and zsh join on the first character of $IFS, bash and ksh93 on space.

$ mksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ yash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ ksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ bash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$

There's a difference between zsh/yash and mksh (version R52 at least) when $IFS is empty:

$ mksh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
12$

The behaviour is more consistent across shells when you use "${a[*]}" (except that mksh still has a bug when $IFS is empty).

In echo $line | ..., that's the usual split+glob operator in all Bourne-like shells but zsh (and the usual problems associated with echo).

That's because in <<< $line, bash does word splitting, (though not globbing) on $line as it's not quoted there and then joins the resulting words with the space character (and puts that in a temporary file followed by a newline character and makes that the stdin of cut).

$ a=a,b,,c bash -c 'IFS=","; sed -n l <<< $a'
a b  c$

tab happens to be in the default value of $IFS:

$ a=$'a\tb'  bash -c 'sed -n l <<< $a'
a b$

The solution with bash is to quote the variable.

$ a=$'a\tb' bash -c 'sed -n l <<< "$a"'
a\tb$

Note that it's the only shell that does that. zsh (where <<< comes from, inspired by the Unix port of rc), ksh93, mksh and yash which also support <<< don't do it.

When it comes to arrays, mksh, yash and zsh join on the first character of $IFS, bash and ksh93 on space.

$ mksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ yash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ ksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ bash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$

There's a difference between zsh/yash and mksh (version R52 at least) when $IFS is empty:

$ mksh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
12$

The behaviour is more consistent across shells when you use "${a[*]}" (except that mksh still has a bug when $IFS is empty).

In echo $line | ..., that's the usual split+glob operator in all Bourne-like shells but zsh (and the usual problems associated with echo).

added 131 characters in body
Source Link
Stéphane Chazelas
  • 584.8k
  • 96
  • 1.1k
  • 1.7k

That's because bash does word splitting, (though not globbing) on $line as it's not quoted there and then joins the resulting words with the space character (and puts that in a temporary file followed by a newline character and makes that the stdin of cut).

$ a=a,b,,c bash -c 'IFS=","; sed -n l <<< $a'
a b  c$
$ a=$'a\tb'  bash -c 'sed -n l <<< $a'
a b$
$ a=$'a\tb' bash -c 'sed -n l <<< "$a"'
a\tb$

The solution with bash is to quote the variable.

Note that it's the only shell that does that. zsh (where <<< comes from, inspired by the Unix port of rc), ksh93, mksh and yash which also support <<< don't do it.

When it comes to arrays, mksh, yash and zsh join on the first character of $IFS, bash and ksh93 on space.

$ mksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ yash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ ksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ bash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$

There's a difference between zsh/yash and mksh (version R52 at least) when $IFS is empty:

$ mksh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
12$

The behaviour is more consistent across shells when you use "${a[*]}" (except that mksh still has a bug when $IFS is empty).

In echo $line | ..., that's the usual split+glob operator in all Bourne-like shells but zsh (and the usual problems associated with echo).

That's because bash does word splitting, (though not globbing) on $line as it's not quoted there and then joins the resulting words with the space character (and puts that in a temporary file followed by a newline character and makes that the stdin of cut.

$ a=a,b,,c bash -c 'IFS=","; sed -n l <<< $a'
a b  c$
$ a=$'a\tb'  bash -c 'sed -n l <<< $a'
a b$
$ a=$'a\tb' bash -c 'sed -n l <<< "$a"'
a\tb$

The solution with bash is to quote the variable.

Note that it's the only shell that does that. zsh (where <<< comes from, inspired by the Unix port of rc), ksh93, mksh and yash which also support <<< don't do it.

When it comes to arrays, mksh, yash and zsh join on the first character of $IFS, bash and ksh93 on space.

$ mksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ yash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ ksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ bash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$

There's a difference between zsh/yash and mksh (version R52 at least) when $IFS is empty:

$ mksh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
12$

The behaviour is more consistent across shells when you use "${a[*]}" (except that mksh still has a bug when $IFS is empty).

That's because bash does word splitting, (though not globbing) on $line as it's not quoted there and then joins the resulting words with the space character (and puts that in a temporary file followed by a newline character and makes that the stdin of cut).

$ a=a,b,,c bash -c 'IFS=","; sed -n l <<< $a'
a b  c$
$ a=$'a\tb'  bash -c 'sed -n l <<< $a'
a b$
$ a=$'a\tb' bash -c 'sed -n l <<< "$a"'
a\tb$

The solution with bash is to quote the variable.

Note that it's the only shell that does that. zsh (where <<< comes from, inspired by the Unix port of rc), ksh93, mksh and yash which also support <<< don't do it.

When it comes to arrays, mksh, yash and zsh join on the first character of $IFS, bash and ksh93 on space.

$ mksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ yash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ ksh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1:2$
$ bash -c 'a=(1 2); IFS=:; sed -n l <<< "${a[@]}"'
1 2$

There's a difference between zsh/yash and mksh (version R52 at least) when $IFS is empty:

$ mksh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
1 2$
$ zsh -c 'a=(1 2); IFS=; sed -n l <<< "${a[@]}"'
12$

The behaviour is more consistent across shells when you use "${a[*]}" (except that mksh still has a bug when $IFS is empty).

In echo $line | ..., that's the usual split+glob operator in all Bourne-like shells but zsh (and the usual problems associated with echo).

Source Link
Stéphane Chazelas
  • 584.8k
  • 96
  • 1.1k
  • 1.7k
Loading