Тогда не используйте оболочку.
#! /usr/bin/perl
use warnings;
use strict;
use Cwd;
use POSIX qw/ strftime /;
my $date = localtime;
my $datef = strftime "%Y%m%d%H%M.%S", localtime;
my $pwd = getcwd;
Результат немного отличается: выходные данные команды date
содержат часовой пояс, но значение $date
выше не будет. Если это проблема, следуйте прекрасному предложению Час. Owens ниже и используйте strftime
, чтобы получить нужный формат.
Ваш саб
sub touchandmail {
`touch $cache -t "$datef"`;
`echo "$msg" | mail -s "$subject" $owner -c $sendto`;
}
потерпит молчание, если что-то пойдет не так. Тихие неудачи - это мерзости. Лучше было бы код по линии
sub touchandmail {
system("touch", "-t", $datef, $cache) == 0
or die "$0: touch exited " . ($? >> 8);
open my $fh, "|-", "mail", "-s", $subject, $owner, "-c", $sendto
or die "$0: could not start mail: $!";
print $fh $msg
or warn "$0: print: $!";
unless (close $fh) {
if ($! == 0) {
die "$0: mail exited " . ($? >> 8);
}
else {
die "$0: close: $!";
}
}
}
Использование system
вместо обратных кавычек более выразительно для вашего намерения, потому что обратные пометки предназначены для захвата выходных данных. Форма system(LIST)
обходит оболочку и беспокоится о цитировании аргументов.
Получение эффекта конвейера оболочки echo ... | mail ...
без оболочки означает, что нам нужно немного проделать сантехническую работу, но выгода - как и в system(LIST)
- не нужно беспокоиться о цитировании оболочки. В приведенном выше коде используется множество аргументов open
:
Для трех или более аргументов, если MODE равен '|-'
, имя файла интерпретируется как команда, к которой должен быть передан вывод, а если MODE равно '-|'
, имя файла интерпретируется как команда, передающая нам выходные данные , В форме с двумя аргументами (и с одним аргументом) следует заменить тире ('-'
) на команду. См. Использование open
для IPC в perlipc для получения дополнительных примеров этого.
Приведенный выше open
разветвляет процесс mail
, и $fh
подключается к его стандартному входу. Родительский процесс (код все еще выполняется touchandmail
) выполняет роль echo
с print $fh $msg
. Вызов close
очищает буферы ввода / вывода ручки и немного больше из-за того, как мы ее открыли:
Если файловый дескриптор получен из канала open
, close
возвращает false, если один из других задействованных системных вызовов завершается ошибкой или если его программа завершает работу с ненулевым состоянием. Если единственная проблема состояла в том, что программа вышла не из нуля, $!
будет установлен в 0. Закрытие канала также ожидает завершения процесса, выполняющегося в канале - в случае, если вы захотите посмотреть на вывод канала впоследствии. - и неявно помещает значение состояния выхода этой команды в $?
и ${^CHILD_ERROR_NATIVE}
.