получение информации из Shell в Perl-переменную [duplicate]

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

Вот пример, передающий число (примитивный тип)

function changePrimitive(val) {
    // At this point there are two '10's in memory.
    // Changing one won't affect the other
    val = val * 10;
}
var x = 10;
changePrimitive(x);
// x === 10

Повторение этого с объектом дает разные результаты:

function changeObject(obj) {
    // At this point there are two references (x and obj) in memory,
    // but these both point to the same object.
    // changing the object will change the underlying object that
    // x and obj both hold a reference to.
    obj.val = obj.val * 10;
}
var x = { val: 10 };
changeObject(x);
// x === { val: 100 }

One еще пример:

function changeObject(obj) {
    // Again there are two references (x and obj) in memory,
    // these both point to the same object.
    // now we create a completely new object and assign it.
    // obj's reference now points to the new object.
    // x's reference doesn't change.
    obj = { val: 100 };
}
var x = { val: 10 };
changeObject(x);
// x === { val: 10}
15
задан brian d foy 17 March 2010 в 15:25
поделиться

3 ответа

Вы можете использовать backtics для выполнения вашей внешней программы и захвата ее stdout и stderr.

По умолчанию обратные выходы отбрасывают stderr и возвращают только stdout внешней программы. Так

$output = `cmd`;

Удерживает stdout программы cmd и discard stderr.

Чтобы записать только stderr, вы можете использовать дескрипторы файла оболочки как:

$output = `cmd 2>&1 1>/dev/null`;

Чтобы захватить как stdout, так и stderr, вы можете сделать :

$output = `cmd 2>&1`;

Используя вышеизложенное, вы не сможете различать stderr с stdout. Для separte stdout из stderr можно перенаправить оба файла в отдельный файл и прочитать файлы:

`cmd 1>stdout.txt 2>stderr.txt`;
25
ответ дан codaddict 23 August 2018 в 00:51
поделиться
  • 1
    Другим способом чтения stdout и stderr отдельно, без использования временных файлов, является использование IPC :: Open3. – dave4420 17 March 2010 в 11:55
  • 2
    Каждый раз, когда используются обратные сигналы, умирает котенок. В оболочке используйте $ (). В perl используйте qx. – William Pursell 17 March 2010 в 16:40
  • 3
    Спасибо за это, я убил 20 котят, прежде чем я использовал qx;) – Severun 21 February 2014 в 04:12
  • 4
    Второе решение cmd 2>&1 1>/dev/null убивает как stdout, так и stderr. Так или иначе оболочка не идентифицирует, что два перенаправления разделены! – L__ 11 April 2016 в 16:27
  • 5

Вы можете использовать IPC :: Open3 или IPC :: Run . Кроме того, прочитайте . Как я могу захватить STDERR из внешней команды из perlfaq8 .

10
ответ дан brian d foy 23 August 2018 в 00:51
поделиться

В большинстве случаев вы можете использовать оператор qx// (или backticks). Он интерполирует строки и выполняет их с оболочкой, поэтому вы можете использовать перенаправления.

  • Для захвата STDOUT команды (STDERR не изменяется):
    $output = `cmd`;
    
  • Чтобы захватить команды STDERR и STDOUT вместе:
    $output = `cmd 2>&1`;
    
  • Чтобы захватить STDERR команды, но отбросить ее STDOUT (порядок здесь важнее):
    $output = `cmd 2>&1 1>/dev/null`;
    
  • Для обмена STDOUT и STDERR команды в чтобы захватить STDERR, но оставить STDOUT для выхода из старого STDERR:
    $output = `cmd 3>&1 1>&2 2>&3 3>&-`;
    
  • Чтобы читать как STDOUT команды, так и ее STDERR отдельно, проще всего перенаправить их отдельно к файлам, а затем прочитать из эти файлы, когда программа выполнена:
    system("program args 1>program.stdout 2>program.stderr");
    
8
ответ дан Eugene Yarmash 23 August 2018 в 00:51
поделиться
Другие вопросы по тегам:

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