Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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
share|improve this question
    
be careful with things like this when using a DEBUG trap, it will cause the meaning to change –  osirisgothra Nov 3 at 17:05

2 Answers 2

up vote 14 down vote accepted

That's not a _< operator, that's a _ argument to pass to read and the < redirection operator. <(cmd) itself is process subtitution (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.

share|improve this answer
    
The command is used at 26:44 in youtube.com/watch?v=CQ6kD48WMxc#t=26m44s - I believe they were just looking to get the size of the iso in MB. –  Steel City Hacker Jun 19 at 13:44

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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