Thread: C system(...) function

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    9

    C system(...) function

    Hello, everybody!

    Here's a part of the code from a program I'm trying to do:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void main (int argc, char* argv[]) {
    
    .....
    
    system("clear");
    system("rm something");
    system("cp something_else something");
    
    .....
    .....
    .....
    
    system("source something");
    
    }
    Now why on Earth doesn't the source command work? It works perfectly when I write it in the console. The other commands I gave using system() (clear, rm and cp) worked just fine. But when I try it through a system function I get:

    sh: source: not found

    And I've tried this even after I gave the bash command (to be sure I'm in bash).

    I've also tried the . (dot) version but it gives me an error too. The file I need to source to is a simple plain text file without any extension to the name (as I said source <that_file> works fine in console.

    Note: I'm doing this on Ubuntu and compiling with gcc -o test test.c

    Thank you in advance,

    Adrian Chitan
    Last edited by Salem; 01-27-2011 at 01:29 AM. Reason: Tag cleanup

  2. #2
    Registered User
    Join Date
    Jan 2011
    Posts
    9
    P.S.
    Forgot to mention something. The program compiles and works almost perfectly. The system("source...") is the only problem.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    This is much more a Linux question than a C question. You know system works in the other commands. From the man page for system():
    system() executes a command specified in command by calling /bin/sh -c
    command, and returns after the command has been completed. During exe-
    cution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT
    will be ignored.
    Your code worked on my fedora box. Notice that the man page says it calls /bin/sh. On my system, that's symlinked to bash. You might want to check that. Typing bash beforehand doesn't guarantee that system() will use a bash shell, it always uses /bin/sh.

    Check the return value of system and of the child process that gets forked by the system() function. There is a small example in the system man page of how to do this. Give us whatever error messages you find and we might be able to better help you.

  4. #4
    Registered User
    Join Date
    Jan 2011
    Posts
    9

    system("source...") return value

    First thank you for responding so quickly. Your idea about /bash/sh before executing the system() command may be the winner. I have to check that.

    The return value of the system("source....") function is: 32512

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by achitan View Post
    First thank you for responding so quickly. Your idea about /bash/sh before executing the system() command may be the winner. I have to check that.
    The thing to remember is that changes made through one call of system() (eg through the source command) don't typically persist through subsequent calls.

    You would probably be better off writing the set of commands you want to execute to a script file of the form;
    Code:
    #!/bin/bash
    
    clear
    rm something
    cp something_else something
    
    .....
    .....
    .....
    
    source something
    and then use a single system() call to execute that script file (which will work if bash is installed, and the script file is executable).

    If need be, your program might create the script file immediately before executing it.

    It might also be worth investigating functions that allow you to perform the required actions directly in code (without relying on a script or a shell that may or may not be installed, let alone working correctly).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Bit Fiddler
    Join Date
    Sep 2009
    Posts
    79
    Probably a $PATH problem.

    Do...
    Code:
    which source
    ...in your bash shell, and put the result in you program.

    E.g.
    Code:
    system("/usr/bin/source something");

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    source is a built-in function of some shells, but not others. IIRC, it is supported by csh and bash, but not by sh (which, under unix, is the default shell executed by the system() function).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  8. #8
    Registered User
    Join Date
    Jan 2011
    Posts
    9

    more on this

    All great answers, thank you. I realize more and more that is a linux problem. Check this out:

    I am in bash and when I do which source I get nothing. Think that's weird? source a_file works.

    I also tried this: /bin/sh and it got me into a shell with a one character prompt and no Tab completition. In here I tried source a_file and I got the exact error that I get when I run my program. So do you know any method to make sh point to bash (meaning that when I write /bin/sh it will go into bash)?

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Yes, this is a unix problem, not a C problem.

    And, no, it's not weird at all. What you are seeing is how the shells work and interact with the system() function.

    The source command (if supported by the current shell) executes a script in the context of the current shell.

    The problem is that each system() call starts a different process for the shell (sh) and things done in one system() call (eg path settings) don't stick in the next system() call.

    As I mentioned in a previous post, either include all the commands needed in a single script file (so all commands are executed by the same shell process) or work out a way to achieve the same results in code, without using the system() function.

    If you have an executable script file then, by convention, a comment on the first line of the form "#!/bin/bash" means that script will be executed using /bin/bash

    Given a command, the call: system("/bin/bash command"); will use bash to execute the command. However, when the system() call returns to the caller, the sh shell (invoked by system()) and the bash shell (which will be invoked by sh) processes will terminate. So, if you're relying on shell settings (eg path settings) to survive between system() calls - you will be disappointed.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  10. #10
    Registered User
    Join Date
    Jan 2011
    Posts
    9
    ok...thank you all for your input. I consider this matter closed. I got it to work using #!/bin/bash at the beggining of the source file and I called it with ./source_file (I also added a chmod u+x command in the program). But it's not what I would expect. I finaly understand what "in the context of the current shell" means. In my source_file I have some export commands to set some environment variables. But after the system function does what it needs to do, it changes shell, and they're gone. So I must find another method.

    Thank you again, all!

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Executing "source" via a system() call will never work, regardless of whether it's a shell built-in or not. System() launches a shell which then changes its own environment, then exits, essentially doing a no-op. To influence your program's environment you have to use setenv() directly.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. measuring system resources used by a function
    By Aran in forum C Programming
    Replies: 1
    Last Post: 03-13-2006, 05:35 PM
  5. I need help with passing pointers in function calls
    By vien_mti in forum C Programming
    Replies: 3
    Last Post: 04-24-2002, 10:00 AM