我想通过php使用ipset来自动运行ips,具体取决于他们的行为。我设法做到了:
echo exec('sudo ipset version');
工作中! ipset v6.20.1, protocol version: 6
echo exec('sudo ipset -A setname 1.2.3.4');
也工作,IP是防火墙。但
echo exec('sudo ipset test setname 1.2.3.4');
不工作(它在终端工作),它什么都不打印。它应该打印1.2.3.4 is in set setname.
即使shell_exec('sudo ipset list setname')
工作,它打印此集中的所有ips。但ipset test
没有通过PHP工作。
这让我花了很多时间才尝试用其他命令测试它。这个命令有什么问题?它为什么没有返回?它在服务器终端中打印常用字符串。
来自documentation的exec()
:
返回值:命令结果的最后一行。 [...]
要获得完整输出,您必须使用&$array
参数:
exec('sudo ipset test setname 1.2.3.4', $lines) ;
$output = implode('\n', $lines) ;
shell_exec()
的文件说:
通过shell执行命令并将完整输出作为字符串返回
PHP内部:
在PHP内部,有两个函数,用于不同的PHP函数:
来自/ext/standard/exec.c
:
exec()
,system()
和passthru()
内部呼吁:
/* {{{ php_exec
* If type==0, only last line of output is returned (exec)
* If type==1, all lines will be printed and last lined returned (system)
* If type==2, all lines will be saved to given array (exec with &$array)
* If type==3, output will be printed binary, no lines will be saved or returned (passthru)
*/
PHPAPI int php_exec(int type, char *cmd, zval *array, zval *return_value)
由PHP_FUNCTION(exec)
,PHP_FUNCTION(system)
和PHP_FUNCTION(passthru)
调用。shell_exec()
内部呼吁:
/* {{{ proto string shell_exec(string cmd)
Execute command via shell and return complete output as string */
PHP_FUNCTION(shell_exec)
这两个函数是完全相同的,除了php_exec
使用php_stream_get_line()
存储行缓冲区,PHP_FUNCTION(shell_exec)
调用_php_stream_copy_to_mem()
将所有数据存储在单个缓冲区中。