skip to Main Content

I have come across the command line wc < f1 f2 and it’s not clear for me what is happening under the hood:

$ echo -n 'a' > f1
$ wc f1
0 1 1 f1

$ echo -n 'bb' > f2
$ wc f2
0 1 2 f2

$ wc < f1 f2
0 1 2 f2

Here the standard input of wc is being redirected to file f1, but I’m also passing file f2 as argument. The output I get is as if I had typed wc f2, i.e.., the standard input is not considered by wc, it seems.

Is wc discarding its standard input (wherever it points to) when it also gets passed a file as argument?

Is wc internally still handling two file descriptors, one for standard input and another for the file it’s being passed as argument, or is it the kernel to "unplug" the standard input file descriptor from file f1 and plug it to file f2 later, in this case?

What else, or what IS actually happening, in a command line like wc < f1 f2?

I am using the Bash shell in Ubuntu 22.04.

Thanks

2

Answers


  1. What else, or what IS actually happening, in a command line like wc < f1 f2?

    wc < f1 f2 executes wc f2 <f1 – executes command wc with one argument f2 and redirects file f1 to standard input.

    wc f2 just prints the counts for file f2. Nothing happens to standard input.

    Is wc discarding its standard input

    No, there is no "discarding", there is "ignoring". wc does not touch standard input at all. "Discarding" would imply the standard input is fully read after wc exits, but it is not.

    Is wc internally still handling two file descriptors

    No, wc is "handling" only f2 file – opening and reading it. You can see what system calls wc is doing by using strace wc f2.

    is it the kernel to "unplug" the standard input file descriptor from file f1 and plug it to file f2 later, in this case?

    There is no "unplugging".

    Login or Signup to reply.
  2. Is wc discarding its standard input (wherever it points to) when it also gets passed a file as argument?

    Ignoring stdin if file arguments are specified is normal behavior for many commands. This is done by the program itself, i.e. by the wc program in this case.

    Often you can use - as a command line argument to use stdin like an ordinary file specified on the command line.

    This behavior is defined by the POSIX specification for wc. My understanding is that it’s implementation-dependant if - is treated as meaning standard input.

    Citing https://man7.org/linux/man-pages/man1/wc.1p.html

    STDIN

    The standard input shall be used if no file operands are
    specified, and shall be used if a file operand is ‘-‘ and the
    implementation treats the ‘-‘ as meaning standard input.
    Otherwise, the standard input shall not be used. See the INPUT
    FILES section.

    Example:

    $ wc foo bar
     1  1  4 foo
     2  2  8 bar
     3  3 12 total
    
    $ wc foo < bar
    1 1 4 foo
    
    $ wc < foo bar
    2 2 8 bar
    
    $ wc - bar < foo
     1  1  4 -
     2  2  8 bar
     3  3 12 total
    
    $ wc < foo - bar
     1  1  4 -
     2  2  8 bar
     3  3 12 total
    
    $ echo foo | wc - bar
          1       1       4 -
          2       2       8 bar
          3       3      12 total
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search