Perl can use the open routine to run shell commands and read or write to them in the manner of C's popen(3S) call.
If a file name argument starts with the pipe character (|), the file name is treated as a command. The command is then executed and the program can be sent input via the print command.
If the file name argument ends with a pipe, the command is executed and that command's output can be read using the <...> facility. Here are two examples:
open(MAIL,"| Mail root"); # send mail to root print MAIL "user \"pat\" is up to no good\n"; close MAIL; # mail is now sent open(WHO,"who|"); # see who's on the system while ($who = <WHO>) { chop $who; ($user,$tty,$junk) = split(/\s+/,$who,3); print "$user is logged on to terminal $tty\n"; } close(WHO);