Sun751 has asked for the wisdom of the Perl Monks concerning the following question:

can any one guide me whats wrong with my code, I am writing the script where I need to change directory,
my $cmd = "cd /cat/bat"; system($cmd); if ($? == -1) { print "Command failed"; }
I think I did right in above code but I am getting following error: "Can't exec "cd"" No such file or directory at crap.pl in line 8, Command failed Any suggestion? please

Replies are listed 'Best First'.
Re: system() command
by ysth (Canon) on Jul 13, 2009 at 01:21 UTC
    "cd" is not a process, it is a shell builtin command that changes the current working directory for that shell process. So system("sh -c 'cd /cat/bat'") would "succeed", but still wouldn't change the working directory of your perl process; use chdir for that.
Re: system() command
by Marshall (Canon) on Jul 13, 2009 at 02:31 UTC
    First, when you are debugging something like this, print the actual return code that Perl sees! You made an erroneous assumption that 256 would be -1! That is true in 8 bit 2's complement math. But that's not true here!

    I personally would always prefer assigning a lexical var for the return code instead of using some "magic" Perl variable ($!). my $rc = system($cmd); #use $rc and perhaps $! also, but $rc is "the error code from system"

    Ysth is completely correct - get the Perl process to change its directory, do not use a shell. That shell is a separate process.

    But a main point here is that when things go "bad", print more stuff, like the return code from system(). Then you see that 256 != -1, etc.

    #!usr/bin/perl -w use strict; my $cmd = "cd /cat/bat"; my $rc = system($cmd); print "rc = $rc\n"; #PRINTS: #The system cannot find the path specified. #rc = 256 $cmd = 'cd C:\temp'; $rc = system($cmd); print "rc = $rc\n"; #PRINTS: #rc = 0
    Update: I would also add that most of the time an O/S error code is "0", zero upon success and non-zero when it fails. As with all things with software, this is not true always, but it is often true. So instead of checking for a comparison with -1 (or 256), better is usually is, if ($x !=0) for the error condition.
      system returns -1 on failure to start the program or an error of the wait(2) system call. My guess is that the OP thinks this is returned in $?, since the return value from system is not being checked.
      Of course, even if the check was correct then it still would not have the desired effect.
        I think we agree that checking the return value of system() call is important - same thing like for a file open or whatever. A more important point here could be that using a system() call for the change directory is the WRONG thing to do.

        Update: Clarification, because that system call does not change the directory of the Perl script, only the directory of the shell script that the Perl script spawned.

Re: system() command
by ambrus (Abbot) on Jul 13, 2009 at 11:38 UTC
Re: system() command
by Anonymous Monk on Sep 05, 2013 at 05:42 UTC
    Simple solution is to add semicolon at the end of command. Like my $cmd = 'cd /cat/bat;';