Find the answer to your Linux question:
Results 1 to 6 of 6
Hello all, I've write a C program just to test redirection and this program just redirect the input to output of the program using getchar() function. The code is as ...
  1. #1
    Just Joined!
    Join Date
    May 2010
    Posts
    9

    [SOLVED] C programming or Bash issue??

    Hello all,

    I've write a C program just to test redirection and this program just redirect the input to output of the program using getchar() function. The code is as follows:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void){
      int c;
      while((c=getchar()) != EOF)
        printf("%c", c);
      
      return 0;
    }
    So I'm testing some redirections of bash and it is going well until a such test:

    Code:
    ./testredirect <(cat Sometextfile)
    This makes the program prompt a user input instead of take it from the subshell instance of cat output.

    I know that if a do this with cat no problem occurs:

    Code:
    cat <(cat Sometextfile)
    Using pipeline no problem occurrs:

    Code:
    cat Sometextfile | ./testredirect
    I wonder if there are some subtle issue and I'm not seeing it. It's a bash issue or a issue with getchar() function?

    Best regards...

  2. #2
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714
    Maybe try

    ./testredirect < $(cat Sometextfile)
    Make mine Arch Linux

  3. #3
    Just Joined!
    Join Date
    May 2010
    Posts
    9
    This doesn't work because bash will try to expand the output like this:

    Code:
    ./testredirect < content of the text ...
    And this ain't what I want

  4. #4
    Linux Newbie theNbomr's Avatar
    Join Date
    May 2007
    Location
    BC Canada
    Posts
    150
    I'm pretty sure the syntax you tried cannot work. Perhaps you meant to use this:
    Code:
    ./testredirect < Sometextfile
    --- rod.
    Stuff happens. Then stays happened.

  5. #5
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
    Posts
    1,117
    Hi.

    There is a tiny bit of magic involved here:
    Code:
    Shell command substitution:
    
      The command  substitution  $(cat file) can be replaced by the
      equivalent but faster $(< file).
    
    Shell process substitution:
    
      Process substitution is supported on systems that support  named
      pipes (FIFOs)  or the /dev/fd method of naming open files.
      It takes the form of <(list) or >(list).
    
    -- excerpt from man bash
    I wrote a quick perl code, copied the c code from the original post, and ran this script:
    Code:
    #!/usr/bin/env bash
    
    # @(#) s1	Demonstrate comparison between perl and c for re-direct.
    
    pe() { for i;do printf "%s" "$i";done; printf "\n"; }
    pl() { pe;pe "-----" ;pe "$*"; }
    
    FILE=${1-data1}
    
    pl " perl, input file on control statement:"
    ./p1 $FILE
    
    pl " perl simple re-direction:"
    ./p1 < $FILE
    
    pl " perl with process substitution:"
    ./p1 <( cat $FILE )
    
    # Compile c code.
    
    gcc one.c
    
    pl " c simple re-direction:"
    ./a.out < $FILE
    
    pl " c with process substitution:"
    ./a.out <( cat $FILE )
    
    exit 0
    The perl code is:
    Code:
    #!/usr/bin/env perl
    
    # @(#) p1	Demonstrate simplest line-by-line copy loop.
    
    if ( defined( $ARGV[0] ) ) {
      print " ARGV[0] is \"$ARGV[0]\"\n";
    }
    while (<>) {
      print;
    }
    The perl worked as I expected, the c code stopped as described by the OP.

    The clue is in the output, pointing to the description of process substitution in the above excerpt:
    Code:
    % ./s1
    
    -----
     perl, input file on control statement:
     ARGV[0] is "data1"
    Line 1 of 2
    Line 2 of 2
    
    -----
     perl simple re-direction:
    Line 1 of 2
    Line 2 of 2
    
    -----
     perl with process substitution:
     ARGV[0] is "/dev/fd/63"
    Line 1 of 2
    Line 2 of 2
    
    -----
     c simple re-direction:
    Line 1 of 2
    Line 2 of 2
    
    -----
     c with process substitution:
    Basically, one needs to look at the argument vector in this simple case, more complicated situations like argument processing would require other actions. But in this case, if the argument exists, then open and read from the file that bash has set up. I don't know how it would work on a system that used the alternate named pipe method, although presumably one can test that explicitly.

    Another way of saying this is that the <( command ) construct is not redirection. It is the creation of a file by the shell, which then replaces that string on the command line with a string representing (ponting to, etc) the file that it has created in /dev. If the code does not process file arguments, and insists on reading STDIN, then the process will seem to hang until terminated or EOF is sent ... cheers, drl
    Last edited by drl; 08-16-2010 at 10:18 AM.
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

  6. #6
    Just Joined!
    Join Date
    May 2010
    Posts
    9
    OMG!! This was freaking awesome drl!! Thanks a lot for this insight!
    I really was away from this tricky answer...

    Although I don't know perl language it is fair that the code was better and shorter than the C one. I'll try perl soon...

    []s, victor

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...