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

Monks, I've dealt with this before with no issues; I've tried a lot of different scenarios so I could try to get this particular issue resolved.

I am trying to pass $nossl to a subprocess in order for it to be handled. For some reason the variable ends up empty once I try to declare it inside of the subprocess.

if ($nossl) { &mkdirs($nossl); }

sub mkdirs { # Can be used to build SSL and non-SSL sites. my $nossl; my $newsite = $nossl; if ( -e "/virtual/$newsite" ) { die "The site \"$newsite\" must already be built!\n"; } else { my %mkdircmd = ( virtual => "mkdir /virtual/$newsite", apachedir => "mkdir /etc/httpd/conf/$newsite", ssl_crt => "mkdir /etc/httpd/conf/$newsite/ssl.crt", ssl_csr => "mkdir /etc/httpd/conf/$newsite/ssl.csr", ssl_key => "mkdir /etc/httpd/conf/$newsite/ssl.crt", logs => "mkdir /var/log/httpd/$newsite" ); system( $mkdircmd {'virtual'} ); system( $mkdircmd {'apachedir'} ); system( $mkdircmd {'ssl_crt'} ); system( $mkdircmd {'ssl_csr'} ); system( $mkdircmd {'ssl_key'} ); system( $mkdircmd {'logs'} ); sleep 2; print "Directories have been built!\n"; } }

Replies are listed 'Best First'.
Re: Passing a variable to a sub process.
by apl (Monsignor) on Apr 02, 2008 at 17:49 UTC
    In your mkdirs subroutine, you should replace

    my $nossl;

    with

    my ( $nossl ) = @_;

    This indicates you want that variable to be populated with the value passed to the subroutine.

    If you called mkdirs with two parameters, your subroutine would need to say

    my ( $nossl, $arg2 ) = @_;

    By the way, you're not calling a subprocess, you're calling a subroutine. A subprocess would be a program or command spawned from your program. A subroutine is a logical part of your program.

    One final note: for arcane reasons, you shouldn't put an ampersand in front of the name of the subroutine you're calling. I know the old Camel book did that, but don't.

    Revised: for clarity.

Re: Passing a variable to a sub process.
by toolic (Bishop) on Apr 02, 2008 at 17:50 UTC
    Inside sub mkdirs, you are declaring a new vaiable, $nossl, which is local to the sub. It is different from the variable of the same name which resides in the calling scope.

    Perhaps what you want to do is:

    #!/usr/bin/env perl use warnings; use strict; my $nossl = 'foo'; mkdirs($nossl); sub mkdirs { my $nossl = shift; print "nossl=$nossl\n"; }

    This prints:

    nossl=foo

    Take a look at shift, perlsub and my.

      I hope to someday be as wise as you two, the depth of understanding you have is quite amazing.

      After the string $nossl was passed into the subroutine I changed some things.
      my $nossl = shift; my $newsite = $nossl;


      Thanks again for your help, I learned a lot from this lesson.
        Since you never use $nossl within your routine, this is equivalent to
        my $newsite = shift;
        There is no significance in using the same name inside and outside the routine. This just says that you want to set $newsite using the first parameter passed to the subroutine.
Re: Passing a variable to a sub process.
by johngg (Canon) on Apr 02, 2008 at 21:56 UTC
    A couple of points:

    • You should omit the ampersand (&) from your subroutine call.
    • You should check for the success or otherwise of the mkdir commands by looking at the return code from system. A non-zero return code would mean something went a bit wonky. It's nice to have faith but your print statement might be a bit optimistic.
    I hope this is of interest.

    Cheers,

    JohnGG

Re: Passing a variable to a sub process.
by mhearse (Chaplain) on Apr 02, 2008 at 18:43 UTC
    You may find this node on scoping useful.