#perl #input #command #prompt #localtime
#perl #ввод #команда #запрос #localtime
Вопрос:
Что у меня есть: Чтобы уточнить, в настоящее время у меня есть функция main, которая указывает исходный каталог и каталог архива назначения. В конце каждого месяца данные за прошлый месяц должны быть перемещены в каталог архива. Я все это разобрал, и хорошо, и до конца. Подпрограмма — это то, что выбирает местное время с помощью функции localtime, а затем, после того как я протестирую несколько условий, она возвращает предыдущий месяц и год в качестве имени новой папки в каталоге архива.
Что мне нужно: у меня есть тестовая настройка в подпрограмме таким образом, что когда $ test = 1, тест выполняется и указывает уникальный год и месяц, которые я могу ввести, тогда как когда test = 0, тест не выполняется и код работает нормально. Я хочу иметь возможность записывать имя файла в командную строку вне кода и иметь своего рода инициализацию, которая будет срабатывать независимо от того, запускаю я тест или нет (например, perl -e archive.pl 1 для запуска теста и perl -e arhcive.pl 0 для запуска кода в обычном режиме).
Я совершенно новичок в Perl, но вот моя подпрограмма:
sub dateDirectory {
my $lt = localtime(); # establish a variable lt for the localtime (includes, sec, min, hour, mday, mon, year)
my $year = $lt->year 1900; # establish a variable year and add 1900 to it as it prints only 100 value
my $mon = $lt->mon 1; # establish a variable mon for month and add 1 as it is a zero-indexed language
my $test = 1; # establish the test variable to run a unit test if test = 1 and don't run it if test = 0
if ($test == 1) {
$year = 2005;
$mon = 3;
}
my $prev_mon = $mon - 1;
my $prev_year = $year - 1;
my $prev_yearmonth = "year$prev_mon";
if ($mon == 1) {
$prev_mon = 12;
$year = $prev_year;
$prev_yearmonth = "$year$prev_mon";
}
my $prev_monlength = length($prev_mon);
if ($prev_monlength == 1) {
$prev_yearmonth = sprintf "%dd", $year, $prev_mon;
}
return ($prev_yearmonth);
}
Ответ №1:
Используется @ARGV
для доступа к параметрам, переданным скрипту perl.
В этом случае я бы посоветовал вам использовать Getopts::Long
для захвата параметров, предназначенных для запуска вашей специальной обработки:
use strict;
use warnings;
use Getopt::Long;
GetOptions(
'test' => my $test,
);
print $test ? "In Testing moden" : "Regular moden";
А затем просто выполните свой скрипт следующим образом, когда вы хотите перейти в тестовый режим:
perl yourscript.pl --test
Комментарии:
1. Если я просто выполняю свой тест, вводя —test в командную строку, как я могу получить доступ к условиям, заданным тестом?
2. Выполнение вашего кода с помощью —test просто устанавливает значение test равным 1?
Ответ №2:
Как сказал Миллер, Getopts::Long
это отличный способ предоставить параметры командной строки вашей программе на perl. Тем не менее, я хотел добавить пример того, как вы могли бы использовать аргумент для установки $test
в 0 или 1.
#!/usr/bin/perl
use strict;
use warnings;
my $test = $ARGV[0];
if ( not defined $test ) {
die "please supply an argmument";
}
if ( $test == 1 ) {
print "test moden";
} else {
print "normal moden";
}
Попробуйте вызвать с его помощью perl test.pl 0
и perl test.pl 1
.
Комментарии:
1. Я вижу использование Getopts ::Long, но я думаю, что ваше решение лучше всего подходит для моей проблемы. Тем не менее, я играл с этим в течение нескольких дней и не могу понять, как включить входной тестовый аргумент в основную процедуру, одновременно включая условия во вспомогательную процедуру. Я попытался поместить мой $ test = @_; в подпрограмму для вызова моего ввода из функции main, но это не сработало.
2.
@_
это массив, и вы вызываете его в скалярном контексте. Попробуйтеmy ($test) = @_;
, и если это не сработает, вы могли бы опубликовать какой-нибудь код и задать другой вопрос.3. Нет, это не сработало. Я могу заставить его работать идеально, если включу весь ваш код (за вычетом предупреждений use strict и use) в свою подпрограмму, где у меня есть все остальные условия. Но если я попытаюсь использовать часть my $ test = $ ARGV[0]; в основной подпрограмме, она перестанет работать. Вот почему я пытался вызвать его в подпрограмму.
4. @user3799015, мне нужно было бы увидеть ваш код, чтобы разобраться в этом. У вас есть
use strict
иuse warnings
в верхней части вашего скрипта, верно? Они указывают на ошибки. Если вы удалите их, ошибки все еще будут, но сообщения не отображаются, и они могут вызвать другие проблемы.5. Да, я делаю. Код функционирует должным образом, я просто не думаю, что он функционирует совсем так, как я намереваюсь, если я не включу весь код в подпрограмму. Мне только что сказали, что тестирование с помощью подпрограммы — плохая практика.
Ответ №3:
Возможно, вы захотите изучить использование CPAN и установить модуль DateTime. Это упрощает выполнение всех видов математики дат правильным образом.
use Carp qw< croak >;
use DateTime;
sub dateDirectory {
my ($year, $month) = @_;
# croak throws an exception at the calling function.
croak "dateDirectory requires both year and month or neither be specifiedn"
if (
($year amp;amp; !$month)
|| (!$year amp;amp; $month)
);
# Get default value of "last month", if not specified.
if( !$year ) {
my $date = DateTime->now()->subtract( months => 1 );
$year = $date->year();
$month = $date->month();
}
return "dd", $year, $month;
}
Вы можете написать тестовый код, который вызывает dateDirectory с любым годом и месяцем, которые вы хотите.
Комментарии:
1. Я обязательно установлю модуль, спасибо! 🙂 Было бы неплохо протестировать код наверняка.
Ответ №4:
Мне нравится perl, но вместо этого я использовал поворот журнала с помощью cron для этой базовой функции.
Комментарии:
1. Добро пожаловать в StackOverflow! Было бы полезно, если бы вы разместили соответствующие цитаты из ваших ссылок в своем ответе, чтобы пользователям не приходилось их искать.