system shell command

Discussion in 'C++' started by Siemel Naran, Feb 4, 2004.

  1. Siemel Naran

    Siemel Naran Guest

    Hi. I'm writing a command shell that reads commands from standard input.
    At this point I have the command in a std::string. Now I want to execute
    this command in the shell. From the Borland newsgroups I learned that there
    is a function in stdlib.h called system.

    int system(const char *command);

    First question, is the system command ANSI compliant. Because I include
    <cstdlib> and write std::system(command.c_str()); it looks like an ANSI C++
    function. But the documentation says it's in POSIX and Win32 only, not in
    ANSI C and ANSI C++.

    Second, and more important, the system command does not appear to respond to
    the cd command. The call std::system("cd ..") runs without error, but does
    not change the working directory, as can be evidenced by calling getcwd of
    dir.h before and after the call to system. The reason is that the system
    command runs within a new child process, and within that the process that
    directory does probably change. After all, if one runs system("exit"), one
    wants the child process to exit, not the parent process.

    So how can I get the system command to change the directory of the parent
    process? Do I have to parse the command, and look for "cd xyz" and change
    the directory to "xyz" using chdir of dir.h? Or is there some way to create
    a system object as a local variable, so that it can know it's state (ie.
    it's directory, environment variables, etc)? If this is the wrong
    newsgroup, can someone please let me know the right newsgroup?

    Thanks.

    --
    +++++++++++
    Siemel Naran
     
    Siemel Naran, Feb 4, 2004
    #1
    1. Advertising

  2. Siemel Naran

    Derk Gwen Guest

    "Siemel Naran" <> wrote:
    # Hi. I'm writing a command shell that reads commands from standard input.
    # At this point I have the command in a std::string. Now I want to execute
    # this command in the shell. From the Borland newsgroups I learned that there
    # is a function in stdlib.h called system.
    #
    # int system(const char *command);
    #
    # First question, is the system command ANSI compliant. Because I include
    # <cstdlib> and write std::system(command.c_str()); it looks like an ANSI C++
    # function. But the documentation says it's in POSIX and Win32 only, not in
    # ANSI C and ANSI C++.

    system(...) is ANSI C, but its evaluation is system specific. So check your
    system documentation. On unices, the system function calls a shell to
    evaluate the command; using that on a unix is sort of like cheating (or
    leads in to endless recursion if it tries to use your shell to evaluate the
    string).

    # Second, and more important, the system command does not appear to respond to
    # the cd command. The call std::system("cd ..") runs without error, but does
    # not change the working directory, as can be evidenced by calling getcwd of
    # dir.h before and after the call to system. The reason is that the system

    On unices, the cd only changes the directory of the current process; the shell
    that interprets the "cd ..." string is a separate process and changes in its
    directory do not affect the directory of the process evaluating the
    system(...) function. Unix shells recognise and interpret the cd command
    directly in the shell itself.

    if (strcmp(command,"cd")==0) {
    change current directory(rest(command));
    }else {
    system(command);
    }

    --
    Derk Gwen http://derkgwen.250free.com/html/index.html
    GERBILS
    GERBILS
    GERBILS
     
    Derk Gwen, Feb 4, 2004
    #2
    1. Advertising

  3. Siemel Naran wrote:

    > Hi. I'm writing a command shell that reads commands from standard input.
    > At this point I have the command in a std::string.


    At this point, your post has become off-topic in comp.lang.c. std::string
    is part of C++ and not C. It is good that you posted to comp.lang.c++, but
    your crossposting to a newsgroup where your question cannot be topical
    suggests that you have neither followed the newsgroups nor checked the FAQs
    before posting. This is a sin.

    > Now I want to execute
    > this command in the shell. From the Borland newsgroups I learned that there
    > is a function in stdlib.h called system.
    >
    > int system(const char *command);


    Since you are using C++, you want to use the C++ header <cstdlib> and not
    the C header <stdlib.h>.

    > First question, is the system command ANSI compliant.


    It is part of ISO (&ANSI) C and C++. The _argument_ has no meaning apart
    from the implementation, OS, in which you use it, however. Its use is,
    even though standard, not portable.




    --
    Martin Ambuhl
     
    Martin Ambuhl, Feb 4, 2004
    #3
  4. Siemel Naran

    Ted Davis Guest

    On Wed, 04 Feb 2004 08:02:27 GMT, "Siemel Naran"
    <> wrote:

    >Hi. I'm writing a command shell that reads commands from standard input.
    >At this point I have the command in a std::string. Now I want to execute
    >this command in the shell. From the Borland newsgroups I learned that there
    >is a function in stdlib.h called system.
    >
    > int system(const char *command);
    >
    >First question, is the system command ANSI compliant. Because I include
    ><cstdlib> and write std::system(command.c_str()); it looks like an ANSI C++
    >function. But the documentation says it's in POSIX and Win32 only, not in
    >ANSI C and ANSI C++.
    >
    >Second, and more important, the system command does not appear to respond to
    >the cd command. The call std::system("cd ..") runs without error, but does
    >not change the working directory, as can be evidenced by calling getcwd of
    >dir.h before and after the call to system. The reason is that the system
    >command runs within a new child process, and within that the process that
    >directory does probably change. After all, if one runs system("exit"), one
    >wants the child process to exit, not the parent process.
    >
    >So how can I get the system command to change the directory of the parent
    >process? Do I have to parse the command, and look for "cd xyz" and change
    >the directory to "xyz" using chdir of dir.h? Or is there some way to create
    >a system object as a local variable, so that it can know it's state (ie.
    >it's directory, environment variables, etc)? If this is the wrong
    >newsgroup, can someone please let me know the right newsgroup?



    No, the first - and most important - question in this MSDOS group is
    "how does system() execute commands in DOS and DOS emulators?". The
    answer is that it invokes the default command processor (shell) and
    passes it the command. If your program is to be the shell, then it
    has to process all the internal command processor commands that you
    support as well as loading and launching any external executables - if
    you wnat to use CD, then your program must intrepret it and invoke the
    necessary interrupt functons to accomplish the underlying tasks. If
    %COMSPEC% points to your program, which it would have to if it were
    the shell, then system() reinvokes your program recursively.


    T.E.D. ()
    SPAM filter: Messages to this address *must* contain "T.E.D."
    somewhere in the body or they will be automatically rejected.
     
    Ted Davis, Feb 4, 2004
    #4
  5. Siemel Naran wrote:
    >
    > Hi. I'm writing a command shell that reads commands from standard input.
    > At this point I have the command in a std::string. Now I want to execute
    > this command in the shell. From the Borland newsgroups I learned that there
    > is a function in stdlib.h called system.
    >
    > int system(const char *command);


    If your program is using system(), then you are not writing a command shell.
    system() starts the command shell and gives it the command to execute. So
    it is your program that could be called by system() and not the other way
    round.


    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Feb 4, 2004
    #5
  6. Siemel Naran

    Siemel Naran Guest

    "Derk Gwen" <> wrote in message
    > "Siemel Naran" <> wrote:


    Thanks to all who replied. My apologies for making the code run in C++
    only. I'll try in C now.

    > # Second, and more important, the system command does not appear to

    respond to
    > # the cd command. The call std::system("cd ..") runs without error, but

    does
    > # not change the working directory, as can be evidenced by calling getcwd

    of
    > # dir.h before and after the call to system. The reason is that the

    system
    >
    > On unices, the cd only changes the directory of the current process; the

    shell
    > that interprets the "cd ..." string is a separate process and changes in

    its
    > directory do not affect the directory of the process evaluating the
    > system(...) function. Unix shells recognise and interpret the cd command
    > directly in the shell itself.
    >
    > if (strcmp(command,"cd")==0) {
    > change current directory(rest(command));
    > }else {
    > system(command);
    > }


    So is the above the only way to do it?

    What I was hoping for is maybe there's a way to open a shell, kind of like
    fopen, and get a handle to this shell. Can anyone please let me know if
    something like the following exists?

    char command[1024];
    strcpy(command, "dir");
    SHELL * shell = shellopen();
    system(shell, command);
    char dir[1024];
    getdir(shell, dir);
    printf("%s", dir);
    shellclose(shell);


    The problem with

    > if (strcmp(command,"cd")==0) {
    > change current directory(rest(command));
    > }else {
    > system(command);
    > }


    is that I have to interpret the command to look for the occurrence of "cd".
    First problem, some shells let you type many commands on one line seperated
    by semicolons like "cd x ; cd y" and now I have to interpret this. And
    second, my program will hardcode the string "cd" but different shells may
    use a different token to denote change directory (though DOS, BASH, TCSH,
    and all the others I've tried do in fact use "cd").

    In my program so far, with the exception of the call to system(...), the
    whole program is ANSI compliant. As soon as I add the parsing capability
    above, my program hardcodes that the change directory command is "cd", and
    that there could be many commands seperated by ";".

    Basically I wrote a streambuf that does reverse incremental history search,
    tab completion, color coding, etc. This streambuf is a replacement for
    stdin or std::cin. Now I want to write a program that behaves like a shell
    (but it's not really a shell because it does not interpret commands itself).
    It will read commands from my special editor, and then run the command in a
    shell. The standard MSDOS shell does not do reverse incremental history
    search, tab completion, color coding (but BASH has all these cool features).

    The structure of my program is

    while true {
    char command[1024];
    mystreambuf(command); // read a command from standard input with reverse
    incremental history, etc.
    system(command); // oops: if command is "cd .." then the directory of the
    shell in which the system command ran does change, but the directory of this
    program does not change -- but I want it to change
    }

    Thanks.

    --
    +++++++++++
    Siemel Naran
     
    Siemel Naran, Feb 5, 2004
    #6
  7. Siemel Naran

    Derk Gwen Guest

    # > if (strcmp(command,"cd")==0) {
    # > change current directory(rest(command));
    # > }else {
    # > system(command);
    # > }
    #
    # So is the above the only way to do it?

    On unix and other systems that treat the current directory this way
    (and even have a current directory notion), it all comes down to either
    this or have each program report back its final environment to its invoker.

    If you aren't trying to write a real shell, but this is simply a functional
    layer function between a real shell for other clients, then one solution is
    to edit the command to reestablish the environment you want, execute the
    command, and then extract the environment out again.

    For example on unix, you might want to save the environmental variables
    and current directory. For bourne shell you can edit the command so
    instead of
    system("command")
    you do something like
    system("cd directory; var=value var=value ... "
    "command; "
    "echo STATUS $? ... ENV $(env) PWD $(pwd) >env.report");
    and then open and parse env.report. (Or use popen and have the report piped
    back to you.)

    Be warned that interpretation of command string to system() is implementation
    dependent, and that on unices, it is also shell dependent.

    --
    Derk Gwen http://derkgwen.250free.com/html/index.html
    I'm not even supposed to be here today.
     
    Derk Gwen, Feb 5, 2004
    #7
  8. Siemel Naran

    mcalhoun Guest

    >>....[snip]....
    >> So is the above the only way to do it?


    >On unix and other systems that treat the current directory this way
    >(and even have a current directory notion), it all comes down to
    >....[snip]....


    I discovered that same "new shell" problem when I was trying to invoke
    SYSTEM from FORTRAN, noticed a FEROCIOUS amount of disk activity for
    each invocation, and finally realized that DOS was ALSO loading a new
    copy of COMMAND.COM for each invocation! Talk about slowdown!

    So, instead of using SYSTEM, I wrote (using direct INTerrupt calls)
    FORTRAN versions of MKDIR, RMDIR, CHDIR, GET/CLR/SET/XFR attributes,
    CopyFile, DeleteFile, CompareFiles, etc.), the problem disappeared,
    and, although the learning curve seemed steep at the time, I've been
    very happy I went to the effort.

    --Myron.
    --
    Five boxes preserve our freedoms: soap, ballot, witness, jury, and cartridge
    PhD EE (retired). "Barbershop" tenor. CDL(PTXS). W0PBV. (785) 539-4448
    NRA Life Member and Certified Instructor (Home Firearm Safety, Rifle, Pistol)
     
    mcalhoun, Feb 6, 2004
    #8
  9. Siemel Naran

    Siemel Naran Guest

    "mcalhoun" <> wrote in message
    news:c00k8n$...

    > I discovered that same "new shell" problem when I was trying to invoke
    > SYSTEM from FORTRAN, noticed a FEROCIOUS amount of disk activity for
    > each invocation, and finally realized that DOS was ALSO loading a new
    > copy of COMMAND.COM for each invocation! Talk about slowdown!
    >
    > So, instead of using SYSTEM, I wrote (using direct INTerrupt calls)
    > FORTRAN versions of MKDIR, RMDIR, CHDIR, GET/CLR/SET/XFR attributes,
    > CopyFile, DeleteFile, CompareFiles, etc.), the problem disappeared,
    > and, although the learning curve seemed steep at the time, I've been
    > very happy I went to the effort.


    Why don't they have a way to create a shell like fopen.

    FILE * file = fopen("abc.txt");
    fwrite(file, ...);
    fclose(file);

    --
    +++++++++++
    Siemel Naran
     
    Siemel Naran, Feb 7, 2004
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    5,850
    Jonathan Bromley
    Feb 18, 2005
  2. Siemel Naran

    system shell command

    Siemel Naran, Feb 4, 2004, in forum: C Programming
    Replies:
    10
    Views:
    2,484
    Joona I Palaste
    Feb 7, 2004
  3. Replies:
    4
    Views:
    1,749
    Terry Hancock
    Apr 23, 2005
  4. Donald Duck

    Best command for running shell command

    Donald Duck, Jul 11, 2006, in forum: Python
    Replies:
    3
    Views:
    425
    iapain
    Jul 11, 2006
  5. Pekka Niiranen
    Replies:
    7
    Views:
    313
    Joe Smith
    Jul 25, 2004
Loading...

Share This Page