Почему exe c () не содержит вывод? - PullRequest
1 голос
/ 05 января 2020

Когда я запускаю команду echo /tmp/stderr{,.pub} | xargs -n 1 ln -sf /dev/stderr && yes | ssh-keygen -t ed25519 -C "" -N "" -f /tmp/stderr > /dev/null; rm /tmp/stderr{,.pub} на оболочке, она возвращает частную / publi c пару ключей, как показано ниже (не волнуйтесь, пара ключей не используется):

blackbox /home/clock # echo /tmp/stderr{,.pub} | xargs -n 1 ln -sf /dev/stderr && yes | ssh-keygen -q -t ed25519 -C "" -N "" -f /tmp/stderr >/dev/null; rm /tmp/stderr{,.pub}
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACA1vZhl2jqtzhEqaqbKwYjLB1OIH8hMPtWB/PWhqeI/QQAAAIj4n5if+J+Y
nwAAAAtzc2gtZWQyNTUxOQAAACA1vZhl2jqtzhEqaqbKwYjLB1OIH8hMPtWB/PWhqeI/QQ
AAAEAtcSI3RLsOo0CXnat4Gs4JENGyDPbGojIT8GU0E+3vUDW9mGXaOq3OESpqpsrBiMsH
U4gfyEw+1YH89aGp4j9BAAAAAAECAwQF
-----END OPENSSH PRIVATE KEY-----
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDW9mGXaOq3OESpqpsrBiMsHU4gfyEw+1YH89aGp4j9B

Но когда я запускаю команду через exec() в PHP, она возвращает саму команду:

blackbox /home/clock # php -f key.php
Array
(
[0] => /tmp/stderr{,.pub} | xargs -n 1 ln -sf /dev/stderr && yes | ssh-keygen -t ed25519 -C "" -N "" -f /tmp/stderr > /dev/null; rm /tmp/stderr{,.pub}
)

Код, который я использую:

<?php
$exec_output = '';
$exec_return = '';

// echo /tmp/stderr{,.pub} | xargs -n 1 ln -sf /dev/stderr && yes | ssh-keygen -t ed25519 -C "" -N "" -f /tmp/stderr > /dev/null; rm /tmp/stderr{,.pub}
$cmd = array('echo', escapeshellarg('/tmp/stderr{,.pub} |'), 'xargs -n 1 ln -sf /dev/stderr', escapeshellarg('&& yes |'), 'ssh-keygen -t ed25519', escapeshellarg('-C "" -N "" -f /tmp/stderr > /dev/null; rm /tmp/stderr{,.pub}'));

exec(implode(' ', $cmd), $exec_output, $exec_return);

print_r($exec_output);
?>

Почему?

PS: я не хочу заполнять сгенерированную пару ключей в файл, даже не в /tmp.

  • PHP: 7.3 .13
  • Пользователь: root

1 Ответ

1 голос
/ 05 января 2020
  1. Расширения пути оболочки не будут работать при передаче в виде строк:

    echo '/tmp/stderr{,.pub}'

    , вместо этого вам нужно использовать без кавычек

    echo /tmp/stderr{,.pub}

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

  3. Здесь нет ввода пользователя, поэтому не нужно ничего избегать.
  4. exec только ловит стандартный вывод, и вы перенаправляете свой в /dev/null.

Измененный массив $cmd выглядит так:

$cmd = array(
  'echo',
  '/tmp/stderr{,.pub}',
  '|',
  'xargs -n 1',
  'ln -sf',
  '/dev/stderr',
  '&&',
  'yes 2>/dev/null',
  '|',
  'ssh-keygen',
  '-t',
  'ed25519',
  '-C',
  '""',
  '-N',
  '""',
  '-f',
  '/tmp/stderr',
  '2>&1',
  '>/dev/null',
  ';',
  'rm',
  '/tmp/stderr{,.pub}'
);
...