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


read bytes _< <(du -bcm random_iso.iso | tail -1); echo $bytes
  • 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


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


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.


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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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