Почему вызов встроенной в Perl exec заставляет эту функцию не возвращаться к своему вызывающему? - PullRequest
1 голос
/ 07 ноября 2010

У меня проблемы с передачей аргументов в функцию, и вызываемая функция не возвращает управление обратно функции, которая ее первоначально вызывала.В основном, я читаю в текстовом файле, который содержит имена пользователей и пароли в массиве.Затем, используя цикл foreach, я передаю имя пользователя и пароль другой функции, но она никогда не возвращается и выполняется только для одного набора параметров;

sub batch {
    open(my $in, "<", "$ARGV[0]") or die "Can't open $ARGV[0]: $!";
 #Read file contents into an array.
 @listOfUsers = <$in>;
 foreach $listOfUsers (@listOfUsers) {
  #Regex to check if txt file conforms to correct syntax.
  if ($listOfUsers !~ /([a-zA-Z]{1}[a-zA-Z0-9]{3,40})\s[a-zA-Z]{1}[a-zA-Z0-9]{3,40}/) {
   print "Please ensure that line $listOfUsers in $ARGV[0] is of the following syntax:\n";
   print "\n<USERNAME> <PASSWORD>\n";
   exit(0);
  } else {
   #split string and call AddUser function
   my ($username, $password) = split(" ",$listOfUsers);
   AddUser($username, $password);
  }
 }
}



sub AddUser {
 exec("infacmd.sh createUser -dn domain -un user -pd pass -hp domain:80 -nu " . $_[0] . " -np " . $_[1] . " -nf test");
}

В принципе, не беспокойтесь о том, что делает функция AddUser.Он просто запускает какой-то файл .sh, который делает то, о чем я не беспокоюсь.В настоящее время я могу добавить только одного пользователя из файла, который я прочитал. Т.е. этот код работает только один раз и не возвращается к функции «batch».

Я попытался добавить 'return ()до конца функции AddUsers, но это не помогает

Спасибо

1 Ответ

11 голосов
/ 07 ноября 2010

exec никогда не возвращается. Как и эквивалентное семейство вызовов в UNIX C, он заменяет текущий процесс на указанный вами. Вы хотите system.

С этих страниц:

exec:
Функция exec выполняет системную команду и никогда не возвращает ; используйте system вместо exec, если хотите, чтобы он вернулся. Он завершается неудачно и возвращает false только в том случае, если команда не существует и выполняется непосредственно, а не через командную оболочку вашей системы.

system:
Действует точно так же, как и exec, за исключением того, что сначала выполняется форк, и родительский процесс ожидает завершения дочернего процесса.


Если вы хотите захватить стандартный вывод программы, вы можете использовать вариант open -with-pipe:

open (HNDL, "myprogram |") || die "Cannot execute.";
while (<HNDL>) {
    # Do something with each line.
}
close (HNDL);

Следующая транскрипция показывает, как вы можете искать строки, содержащие определенную строку (123 в этом случае) из определенной команды (ls -al xx* в этом случае):

pax> ls -al xx*
    -rw-r--r-- 1 pax None  10 2010-06-13 19:51 xx
    -rw-r--r-- 1 pax None 123 2010-05-05 23:39 xx.py

pax> cat qq.pl
    open (HNDL, "ls -al xx* |") || die "Cannot execute.";
    while (<HNDL>) {
        if (/123/) {
            print;
        }
    }
    close (HNDL);

pax> perl qq.pl
    -rw-r--r-- 1 pax None 123 2010-05-05 23:39 xx.py
...