为什么 exec() 不包含输出?
Why is exec() not containing the output?
当我在 shell 上 运行 命令 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}
时,它返回 private/public 密钥对,如下所示(不用担心,密钥对未被使用):
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
但是当我 运行 通过 PHP 中的 exec()
命令时,它返回了命令本身:
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
Shell 路径扩展在作为字符串传递时不起作用:
echo '/tmp/stderr{,.pub}'
相反,您需要使用不带引号的
echo /tmp/stderr{,.pub}
您不能用程序选项本身引用参数,它将被视为一个参数。
- 这里没有用户输入,所以不需要转义。
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}'
);
当我在 shell 上 运行 命令 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}
时,它返回 private/public 密钥对,如下所示(不用担心,密钥对未被使用):
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
但是当我 运行 通过 PHP 中的 exec()
命令时,它返回了命令本身:
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
Shell 路径扩展在作为字符串传递时不起作用:
echo '/tmp/stderr{,.pub}'
相反,您需要使用不带引号的
echo /tmp/stderr{,.pub}
您不能用程序选项本身引用参数,它将被视为一个参数。
- 这里没有用户输入,所以不需要转义。
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}'
);