Когда правильное время (и неправильное время) для использования обратных галочек?

Правильный ответ был следующим:

SELECT 
 1.0*
 ((COUNT(*) FILTER(WHERE "stitch_jira"."issues"."fields__status__statusCategory__name"='Done'
 AND "stitch_jira"."issues"."fields__project__key"='FLUM'
 AND "stitch_jira"."issues"."fields__issuetype__name"='Task'))
 +
 (COUNT(*) FILTER(WHERE "stitch_jira"."issues"."fields__status__statusCategory__name"='Done'
 AND "stitch_jira"."issues"."fields__project__key"='FLUM'
 AND "stitch_jira"."issues"."fields__issuetype__name"='Story')))
 /
 ((COUNT(*) FILTER(WHERE "stitch_jira"."issues"."fields__status__statusCategory__name" IN('To Do','In Progress','Done')
 AND "stitch_jira"."issues"."fields__project__key"='FLUM'
 AND "stitch_jira"."issues"."fields__issuetype__name"='Task'))
 +
 (COUNT(*) FILTER(WHERE "stitch_jira"."issues"."fields__status__statusCategory__name" IN('To Do','In Progress','Done')
 AND "stitch_jira"."issues"."fields__project__key"='FLUM'
 AND "stitch_jira"."issues"."fields__issuetype__name"='Story')))
FROM "stitch_jira"."issues"

Проблема заключалась в том, что не было достаточно жесткой привязки условия ИЛИ, и он получал данные в своих расчетах за пределами отфильтрованного проекта. ]

14
задан raldi 22 September 2008 в 16:12
поделиться

14 ответов

Несколько человек уже упомянули, что необходимо только использовать обратные галочки когда:

  • Необходимо получить (или подавить), вывод.
  • Там не существует никакая встроенная функция или модуль Perl, чтобы сделать ту же задачу, или у Вас есть серьезное основание не использовать модуль или встроенный.
  • Вы санируете свой вход.
  • Вы проверяете возвращаемое значение.

К сожалению, вещи как проверка возвращаемого значения правильно могут быть довольно сложными. Это умирало к сигналу? Это работало к завершению, но возвращало забавный статус выхода? Стандартные способы попытаться интерпретировать $? просто ужасны.

Я рекомендовал бы использовать IPC:: Система:: Простой модуль capture() и system() функции, а не обратные галочки. capture() функционируйте работы точно так же, как обратные галочки, за исключением того, что:

  • Это обеспечивает подробную диагностику, если команда не запускается, уничтожается сигналом или возвращает неожиданное значение выхода.
  • Это предоставляет подробной диагностике, если передано испорченные данные.
  • Это обеспечивает легкий механизм для определения приемлемых значений выхода.
  • Это позволяет Вам называть обратные галочки без оболочки, если Вы хотите.
  • Это обеспечивает надежные механизмы для предотвращения оболочки даже при использовании отдельного аргумента.

Команды также последовательно работают через операционные системы и версии Perl, в отличие от встроенного Perl system() который не может проверить на испорченные данные при вызове с несколькими аргументами на более старых версиях Perl (например, 5.6.0 с несколькими аргументами), или который может назвать оболочку так или иначе в соответствии с Windows.

Как пример, следующий фрагмент кода сохранит результаты вызова к perldoc в скаляр, избегает оболочки и выдает исключение, если страница не может быть найдена (так как perldoc возвращается 1).

#!/usr/bin/perl -w
use strict;
use IPC::System::Simple qw(capture);

# Make sure we're called with command-line arguments.
@ARGV or die "Usage: $0 arguments\n";

my $documentation = capture('perldoc', @ARGV);

IPC:: Система:: Простой чистый Perl, работы над 5.6.0 и выше, и не имеет никаких зависимостей, которые обычно не шли бы с Вашим распределением Perl. (В Windows это зависит от Win32:: модуль, который идет и с Perl ActiveState и Земляники).

Отказ от ответственности: Я - автор IPC:: Система:: Простой, таким образом, я могу показать некоторую предвзятость.

22
ответ дан 1 December 2019 в 05:55
поделиться

Независимо от того, что Вы делаете, а также очистка входа и проверка возвращаемого значения Вашего кода, удостоверьтесь, что Вы называете любые внешние программы с их явным, полным путем. например, скажите

my $user = `/bin/whoami`;

или

my $result = `/bin/cp $from $to`;

, Высказывание просто "whoami" или "CP" рискуют случайно выполнять команду кроме того, что Вы предназначили, если путь пользователя изменяется - который является уязвимостью системы обеспечения безопасности, которую злонамеренный взломщик мог попытаться использовать.

2
ответ дан 1 December 2019 в 05:55
поделиться

Ваш пример, плохой, потому что существует жемчуг builtins, чтобы сделать это, которые являются портативными и обычно более эффективными, чем альтернатива обратной галочки.

Они должны использоваться только, когда нет никакого встроенного Perl (или модуль) альтернатива. Это - и для обратных галочек и для системы () вызовы. Обратные галочки предназначаются для получения вывода выполняемой команды.

1
ответ дан 1 December 2019 в 05:55
поделиться

Обратные галочки, как только предполагается, используются, когда Вы хотите получить вывод. Используя их здесь "выглядит глупым". Это идет в подсказку любой смотрящий на Ваш код в то, что Вы не очень знакомы с Perl.

обратные галочки Использования, если Вы хотите получить вывод. Используйте систему, если Вы хотите выполнить команду. Одним преимуществом, которое Вы получите, является способность проверить статус возврата. Используйте модули, если это возможно, для мобильности. В этом случае File::Copy отвечает всем требованиям.

1
ответ дан 1 December 2019 в 05:55
поделиться

Perl имеет раздвоение личности. С одной стороны, это - большой язык сценариев, который может заменить использование оболочки. В этом виде одноразового использования I-watching-the-outcome обратные галочки удобны.

При использовании язык программирования обратных галочек нужно избежать. Это - отсутствие проверки ошибок и, если отдельные обратные галочки программы выполняются, может избежаться, эффективность получена.

Кроме вышеупомянутого, системная функция должна использоваться, когда вывод команды не используется.

0
ответ дан 1 December 2019 в 05:55
поделиться

Обратные галочки для любителей. Пуленепробиваемым решением является "Безопасный Канал, Открытый" (см. "человека perlipc"). Вы должностное лицо Ваша команда в другом процессе, который позволяет Вам первому futz с STDERR, setuid, и т.д. Преимущества: это делает не , полагаются на оболочку для парсинга @ARGV, в отличие от открытого (" $cmd$args | "), который ненадежен. Можно перенаправить STDERR и изменить пользовательские полномочия, не изменяя поведение основной программы. Это является более подробным, чем обратные галочки, но можно перенести его в собственную функцию как run_cmd ($cmd, @args);


sub run_cmd {
  my $cmd = shift @_;
  my @args = @_;

  my $fh; # file handle
  my $pid = open($fh, '-|');
  defined($pid) or die "Could not fork";
  if ($pid == 0) {
    open STDERR, '>/dev/null';
    # setuid() if necessary
    exec ($cmd, @args) or exit 1;
  }
  wait; # may want to time out here?
  if ($? >> 8) { die "Error running $cmd: [$?]"; }
  while (<$fh>) {
    # Have fun with the output of $cmd
  }
  close $fh;
}
0
ответ дан 1 December 2019 в 05:55
поделиться

В целом, лучше использовать система вместо обратных галочек потому что:

  1. система поощряет вызывающую сторону проверять код возврата команды.

  2. система позволяет нотацию "косвенного дополнения", которая более безопасна и добавляет гибкость.

  3. Обратные галочки культурно связываются для окружения сценариев, которые не могли бы быть распространены среди читателей кода.

  4. Обратные галочки используют минимальный синтаксис для того, что может быть тяжелой командой.

Одна причина пользователи могли бы работаться временно для использования обратных галочек вместо [1 119], система должна скрыть STDOUT от пользователя. Это более легко и гибко выполняется путем перенаправления потока STDOUT:

my $cmd = 'command > /dev/null';
system($cmd) == 0 or die "system $cmd failed: $?"

Далее, избавление от STDERR легко выполняется:

my $cmd = 'command 2> error_file.txt > /dev/null';

В ситуациях, где имеет смысл использовать обратные галочки, я предпочитаю использовать qx {} , чтобы подчеркнуть, что существует тяжелое появление команды.

, С другой стороны, имея Другой способ Сделать Это может действительно помочь. Иногда просто необходимо видеть то, что команда печатает к STDOUT. Обратные галочки при использовании в качестве в сценариях оболочки являются просто правильным инструментом для задания.

1
ответ дан 1 December 2019 в 05:55
поделиться

Правило просто: никогда не используйте обратные галочки, если можно найти, что встроенное делает то же задание, или если их устойчивый модуль на CPAN, который сделает это для Вас. Обратные галочки часто полагаются на непортативный код и даже если Вы не заражаете переменные, можно все еще открыть себя много дыр в системе безопасности.

Никогда обратные галочки использования с пользовательскими данными, если Вы очень плотно не указали то, что позволяется (не, что запрещено - Вы пропустите вещи)! Это очень, очень опасно.

11
ответ дан 1 December 2019 в 05:55
поделиться

Другой способ получить stdout (в дополнение к изодромному с предварением и коду выхода) состоит в том, чтобы использовать IPC:: Open3 possibily, инвертирующий использование и системы и обратных галочек.

5
ответ дан 1 December 2019 в 05:55
поделиться

Обратные галочки должны использоваться, если и только если необходимо получить вывод команды. Иначе система () должна использоваться. И, конечно, если существует функция Perl или модуль CPAN, который делает задание, это должно использоваться вместо также.

В любом случае, две вещи сильно поощряются:

Первый, санируют все исходные данные: режим Use Taint (-T), если код выставляется возможному недоверяемому входу. Даже если это не, удостоверьтесь, что обработали (или предотвратили) броские символы как пространство или три вида кавычки.

114-секундный, проверяют код возврата для проверки команды, за которой следуют. Вот пример того, как сделать так:

my $cmd = "./do_something.sh foo bar";
my $output = `$cmd`;

if ($?) {
   die "Error running [$cmd]";
}
6
ответ дан 1 December 2019 в 05:55
поделиться

Используйте обратные галочки, когда Вы захотите собрать вывод из команды.

Иначе system() лучший выбор, особенно если Вы не должны вызывать оболочку для обработки парсинга команды или метасимволов. Можно избежать, что путем передачи списка системе (), например, system('cp', 'foo', 'bar') (однако Вы, вероятно, добились бы большего успеха для использования модуля для того конкретный пример :))

5
ответ дан 1 December 2019 в 05:55
поделиться

Для случая Вы показываете использование File::Copy , модуль является, вероятно, лучшим. Однако для ответа на вопрос, каждый раз, когда я должен выполнить систему, управляют, чтобы я обычно полагался IPC:: Run3. Это обеспечивает большую функциональность, такую как сбор кода возврата и стандартного вывода и вывода ошибок.

3
ответ дан 1 December 2019 в 05:55
поделиться

Из "perlop" страницы справочника:

, Который не означает, необходимо стараться изо всех сил избегать обратных галочек, когда они - правильный способ сделать что-то. Perl был сделан быть языком связующего звена, и одной из вещей, которые он склеивает, являются команды. Просто поймите то, во что Вы вовлекаете себя.

3
ответ дан 1 December 2019 в 05:55
поделиться

В Perl всегда существует больше чем один способ сделать что-либо, что Вы хотите. Основная точка обратных галочек должна получить стандартный вывод команды оболочки в переменную Perl. (В Вашем примере, что-либо, что печать команды CP будет возвращена вызывающей стороне.) Оборотная сторона использования обратных галочек в Вашем примере является Вами, не проверяют возвращаемое значение команды оболочки; CP могло перестать работать, и Вы не заметите. Можно ли использовать это со специальным $ переменной Perl?. Когда я хочу выполнить команду оболочки, я склонен использовать система :

system("cp $from $to") == 0
    or die "Unable to copy $from to $to!";

(Также замечают, что это перестанет работать на именах файлов со встроенными пробелами, но я предполагаю, что это не точка вопроса.)

Вот изобретенный пример того, где обратные галочки могли бы быть полезными:

my $user = `whoami`;
chomp $user;
print "Hello, $user!\n";

Для более сложных случаев, можно также использовать , открывают как канал:

open WHO, "who|"
    or die "who failed";
while(<WHO>) {
    # Do something with each line
}
close WHO;
4
ответ дан 1 December 2019 в 05:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: