is it a bug with system()?

1

19840129

system("cd") return -1 and set errno msg "cd :no this file or
directory"
so it is not like c, "cd" may not be send to shell to explain.
but the perldoc -f system says that it is.
so is it bug? if not ,can somebody tell me why even system("cd") has no
use?

sorry for my poor English
 
J

Josef Möllers

19840129 said:
system("cd") return -1 and set errno msg "cd :no this file or
directory"
so it is not like c, "cd" may not be send to shell to explain.
but the perldoc -f system says that it is.
so is it bug? if not ,can somebody tell me why even system("cd") has no
use?

You'll start a shell which will change to the current user's home directory
and then exit.
What use should that have?
 
P

prawn

19840129 said:
system("cd") return -1 and set errno msg "cd :no this file or
directory"
so it is not like c, "cd" may not be send to shell to explain.
but the perldoc -f system says that it is.
so is it bug? if not ,can somebody tell me why even system("cd") has no
use?

sorry for my poor English

This is windows, right? "cd" is an internal command, so a system call
won't find a corresponding .exe/.cmd/.bat/.com file on the path.
 
X

xcm

Josef Möllers said:
You'll start a shell which will change to the current user's home directory
and then exit.
What use should that have?


en ,I know it,but why system("cd") return -1 ?
it is not the behavior as perldoc -f system() describes
 
X

xcm

prawn said:
This is windows, right? "cd" is an internal command, so a system call
won't find a corresponding .exe/.cmd/.bat/.com file on the path.



oh,no,it's in linux and in windows it acts well;
the doc says like :
"the system function does a fork() and the parent wait the exit of the child
which uses a shell to execute the command just like in C' system "
 
X

xcm

and I know "cd" is a internal command of shell.

I only want to know if system() always pass the command to shell or derectly
use exec family to execute the command.
 
A

Anno Siegel

xcm said:
and I know "cd" is a internal command of shell.

I only want to know if system() always pass the command to shell or derectly
use exec family to execute the command.

That is explained in "perldoc -f system" (and, perhaps, "perldoc -f exec").

The answer is that "system 'cd'" does not use a shell. Since (under Unix,
normally) a command named "cd" doesn't exist, the call fails with the
error message you've seen. If you change it to "system 'cd;'" Perl
will use a shell and you won't see an error. It still doesn't make
sense to do that.

Anno
 
L

Lukas Mai

19840129 said:
system("cd") return -1 and set errno msg "cd :no this file or
directory"
so it is not like c, "cd" may not be send to shell to explain.
but the perldoc -f system says that it is.
so is it bug? if not ,can somebody tell me why even system("cd") has no
use?

perldoc -f system:
[...]
| If there is only one scalar argument, the argument is checked for shell
| metacharacters, and if there are any, the entire argument is passed to
| the system's command shell for parsing (this is "/bin/sh -c" on Unix
| platforms, but varies on other platforms). If there are no shell
| metacharacters in the argument, it is split into words and passed
| directly to "execvp", which is more efficient.

"cd" doesn't contain shell metacharacters, so perl tries to exec it
directly, which fails for obvious reasons. A simple "workaround" is to
use a shell metacharacter, as in system("cd;"); however, this still
won't change the working directory of your script. For that you should
see perldoc -f chdir.

HTH, Lukas
 
T

Tad McClellan

xcm said:
and I know "cd" is a internal command of shell.


So then,

system 'cd';

is totally useless.

What is it that you are really trying to accomplish?

Do you know that you can change the current working directly in
a manner that may actually be useful for something?

perldoc -f chdir

I only want to know if system() always pass the command to shell or derectly
use exec family to execute the command.


The docs for system() answer your question:

Note that argument processing varies depending on the
number of arguments. If there is more than one argument in LIST,
or if LIST is an array with more than one value, starts the program
given by the first element of the list with arguments given by the
rest of the list. If there is only one scalar argument, the argument
is checked for shell metacharacters, and if there are any, the
entire argument is passed to the system's command shell for parsing
(this is C</bin/sh -c> on Unix platforms, but varies on other
platforms). If there are no shell metacharacters in the argument,
it is split into words and passed directly to C<execvp>, which is
more efficient.

Q: How many args are you passing to system()?

A: One.

Q: Does that single argument contain any shell metacharacters?

A: No.

Q: Will system() invoke a shell then?

A: No.

So attempting to run a shell builtin will fail, because there is no shell.


You could call it with one arg that _does_ contain shell metacharacters:

system 'cd ~'


Or, probably better, call system with a list, and explicitly
call the shell that you want:

system '/bin/bash', '-c', 'cd'
 
J

Joe Smith

xcm said:
en ,I know it,but why system("cd") return -1 ?
it is not the behavior as perldoc -f system() describes

It is behaving exactly as documented in 'perldoc -f system()'.

perl -le 'print system("foobar")," error=$!"'
-1 error=No such file or directory

That error is correct; there is no executable file by that name in
any of the directories specified by $ENV{PATH}.

perl -le 'print "$_/cd does ", -f "$_/cd" ? "" : "not ", "exist" for split /:/,$ENV{PATH}'

The "cd" command is built-in to the shell, it is _not_ an executable binary.

-Joe
 
B

Bart Lateur

19840129 said:
system("cd") return -1 and set errno msg "cd :no this file or
directory"
so it is not like c, "cd" may not be send to shell to explain.
but the perldoc -f system says that it is.
so is it bug? if not ,can somebody tell me why even system("cd") has no
use?

single word command lines do not use the shell, they try to directly
call the program.

And there is no program called "cd", as it is a built-in from the shell.

If you were to add another "word", it should more or less work, like:

system("cd .")

I'm saying "more or less", because the net result of this command would
still be nothing. You see, even if the child program changes its current
directory, the parent process, your Perl script, wouldn't see it. Parent
processes don't inherit from their children.

Why aren't you just using the builtin, chdir()?

<http://perldoc.perl.org/functions/chdir.html>
 
P

Peter J. Holzer

Bart said:
single word command lines do not use the shell, they try to directly
call the program.

And there is no program called "cd", as it is a built-in from the
shell.

Actually, POSIX requires that a program called "cd" exists. It does
exist on HP-UX and there is probably some obscure package in your
favourite Linux distribution which contains it (which nobody ever
installs because "cd" as a command is extremely useless).

hp
 
A

Anno Siegel

Dan Mercer said:
: Bart Lateur wrote:
: > single word command lines do not use the shell, they try to directly
: > call the program.
: >
: > And there is no program called "cd", as it is a built-in from the
: > shell.
:
: Actually, POSIX requires that a program called "cd" exists. It does
: exist on HP-UX and there is probably some obscure package in your
: favourite Linux distribution which contains it (which nobody ever
: installs because "cd" as a command is extremely useless).

It is useful in find. Can't think of anything else.

Changing your current directory is useful, not only in find. A
*program* that does nothing but change its directory is useless
because it has no effect on the calling process.

Does POSIX indeed demand the existence of a stand-alone cd command?
Perldoc POSIX doesn't mention it.

Anno
 
P

Peter J. Holzer

Anno said:
Changing your current directory is useful, not only in find. A
*program* that does nothing but change its directory is useless
because it has no effect on the calling process.

The calling process can use the exit code of the cd program to check
whether the parameter is a directory which it can chdir into. So

find / -exec cd {} \; -print

prints all directories accessible to the invoking user. Whether that
is useful, is debatable. I never needed it in 20 years of using Unix,
but requirements differ.

Does POSIX indeed demand the existence of a stand-alone cd command?

Yes, see
http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap01.html#tag_01_13

| Table: Regular Built-In Utilities
[...]
cd
[...]
| However, all of the standard utilities, including the regular
| built-ins in the table, but not the special built-ins described in
| Special Built-In Utilities , shall be implemented in a manner so that
| they can be accessed via the exec family of functions as defined in
| the System Interfaces volume of IEEE Std 1003.1-2001 and can be
| invoked directly by those standard utilities that require it ( env,
| find, nice, nohup, time, xargs).

(cd is one of the regular builtins)
Perldoc POSIX doesn't mention it.

POSIX.pm contains bindings to POSIX library functions, not to POSIX
commands.

hp
 
A

Anno Siegel

Peter J. Holzer said:
The calling process can use the exit code of the cd program to check
whether the parameter is a directory which it can chdir into. So

find / -exec cd {} \; -print

prints all directories accessible to the invoking user. Whether that
is useful, is debatable. I never needed it in 20 years of using Unix,
but requirements differ.

Well... yes. I'd probably check permissions, but "cd" may be simpler.
Does POSIX indeed demand the existence of a stand-alone cd command?

Yes, see
http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap01.html#tag_01_13

| Table: Regular Built-In Utilities
[...]
cd
[...]
| However, all of the standard utilities, including the regular
| built-ins in the table, but not the special built-ins described in
| Special Built-In Utilities , shall be implemented in a manner so that
| they can be accessed via the exec family of functions as defined in
| the System Interfaces volume of IEEE Std 1003.1-2001 and can be
| invoked directly by those standard utilities that require it ( env,
| find, nice, nohup, time, xargs).

(cd is one of the regular builtins)

Thanks for the quotation.

I can't help feeling that in extending the requirement to a whole list,
one or the other function may have slipped in that doesn't make much
sense as a stand-alone program.

Anno
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,184
Messages
2,570,973
Members
47,529
Latest member
JaclynShum

Latest Threads

Top