4

What is the difference between using _< and < for stdin when using process substitution. This is done using bash.

Example:

read bytes _< <(du -bcm random_iso.iso | tail -1); echo $bytes
1
  • be careful with things like this when using a DEBUG trap, it will cause the meaning to change Nov 3, 2014 at 17:05

2 Answers 2

16

That's not a _< operator, that's a _ argument to pass to read and the < redirection operator. <(cmd) itself is process substitution (that expands to a filename that points to a pipe).

What that does is run:

read bytes _  < /proc/self/fd/x

Where the fd x is the reading end of a pipe.

At the other (writing) end of the pipe, a background subshell process is executing du -bcm random_iso.iso | tail -1 with its stdout redirected to that pipe.

So read will store in the $bytes variable the first word of the last line of the output of du -bcm, and the rest of the line in the $_ variable.

Now I don't know where that du -bcm makes sense. None of -b, -c nor -m options are standard. While -c is quite common and is for giving the cumulative size, with GNU du, -b is to get the file size (not disk usage) in bytes, while -m is to get the size rounded up to the next mebibyte so they would be conflicting options (though maybe they used -b for its side-effect of enabling --apparent-size). FreeBSD du has -m (for mebibytes), no -b, Solaris has neither...

It looks like it was meant as a convoluted way to write:

wc -c < random_iso.iso

Or:

du --apparent-size -cm random_iso.iso | awk 'END{print $1}'

If they indeed wanted the file size rounded up to the next mebibyte on a GNU system.

1
4

As mentioned, _< isn't a redirect. This is passing _ as the final argument to read. The < is then interpreted as a separate redirect operator redirecting the process substitution's output to stdin.

It has become conventional in Bash scripts to use _ as a "throwaway variable" in conjunction with the read builtin. In bash, _ is a special variable that gets set to the final argument of a command after each command is executed. In this case, it means bytes will be assigned the first field, and the remaining fields are discarded into the _ variable, instead of assigning all remaining fields into bytes.

While this is a convention, there are a number of good reasons to avoid abusing _ in this way.

  • This behavior of _ is not specified by POSIX. Most shells won't do anything special with it.
  • In zsh, _ has the readonly attribute, and using this will cause the shell to throw an error.
  • In mksh, _ only has bash's behavior in interactive mode. In a non-interactive script, _ is used for a different purpose and isn't assigned anything after each command.
  • in ksh93, _ is only set to the last argument of the last command on a line. Commands must be physically located on separate lines of code in order to make use of _. Additionally, _ in ksh93 is overloaded to have many many other uses in various contexts, so assigning to _ for this purpose isn't recommended and will do different things depending on context.

I recommend putting a space before a redirect to make things clearer. I put some guidelines on good redirect style in this article.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .