Вместо того, чтобы вызывать команду и читать ее вывод, я бы предложил использовать IPC :: Open2 или, возможно, IPC :: Open3 и использовать ваш процесс B в качестве фильтра: writeв, зачитать.На этом этапе вы полностью ликвидируете оболочку.И, по моему опыту, удаление оболочки - это всегда хорошо.
А затем, чтобы упростить задачу, вы запускаете команду через IPC :: Open [23], записываете в нее сериализованные данные (черезJSON или Storable), закройте канал записи (чтобы другая сторона получила eof) и дождитесь данных.С другой стороны, прочитайте stdin, десериализуйте его, используйте его и снова сериализуйте возвращаемые данные.Вернитесь на сервер CGI, десериализуйте полученные данные, и все готово.Это также работает очень хорошо, если вам нужно выполнить двойной или тройной переход (ssh через одну машину к ssh к другой).
Можно поставить достаточно кавычек, чтобы заставить его работать так, как вы хотите.Это умеренно больно.Однако вот несколько советов в этом направлении.Во-первых, найдите что-то на CPAN , которое обрабатывает цитирование для вас. String :: ShellQuote может работать.Во-вторых, по возможности избегайте раковины.То есть вместо open my $pipe, "ssh $server '$cmd' |"
используйте open my $pipe, '-|', 'ssh', $server, $cmd
.Это позволит избежать локальной оболочки.И это уменьшает количество раз, когда вам приходится беспокоиться о цитировании чего-либо.Но вам придется пересматривать все каждый раз, когда вы делаете новый отскок, поскольку каждая удаленная машина все еще будет использовать удаленную оболочку.