472,133 Members | 1,172 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,133 software developers and data experts.

system shell command

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
Nov 14 '05 #1
10 16214
"Siemel Naran" <Si*********@REMOVE.att.net> 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
Nov 14 '05 #2
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
Nov 14 '05 #3
On Wed, 04 Feb 2004 08:02:27 GMT, "Siemel Naran"
<Si*********@REMOVE.att.net> 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. (td****@gearbox.maem.umr.edu)
SPAM filter: Messages to this address *must* contain "T.E.D."
somewhere in the body or they will be automatically rejected.
Nov 14 '05 #4
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
kb******@gascad.at
Nov 14 '05 #5
"Derk Gwen" <de******@HotPOP.com> wrote in message
"Siemel Naran" <Si*********@REMOVE.att.net> 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
Nov 14 '05 #6
# > 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.
Nov 14 '05 #7
Siemel Naran wrote:
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 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
}


Try something like

FILE *shell = popen("sh", "w"); // replace "sh" by the shell you have
fputs(command, shell); // don't forget the \n at the end of command
Nov 14 '05 #8
>>....[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)
Nov 14 '05 #9
"mcalhoun" <mc******@ksu.edu> wrote in message
news:c0********@unix1.cc.ksu.edu...
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
Nov 14 '05 #10
mcalhoun <mc******@ksu.edu> scribbled the following
on comp.lang.c:
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.


Yikes. Are you sure you're not a chair? (comp.lang.c in-joke)

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"I am not very happy acting pleased whenever prominent scientists overmagnify
intellectual enlightenment."
- Anon
Nov 14 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Ayesha Ahsan | last post: by
1 post views Thread by Wayne Witzel III | last post: by
9 posts views Thread by Joerg Schuster | last post: by
8 posts views Thread by Siemel Naran | last post: by
2 posts views Thread by Xah Lee | last post: by
16 posts views Thread by BHARAT MEHTA | last post: by
11 posts views Thread by jobs239 | last post: by
12 posts views Thread by Bob | last post: by
16 posts views Thread by Anonymous User | last post: by
12 posts views Thread by tom_kuehnert | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.