我希望创建一个onbininer,将stdin流转换为受密码保护的zip存档中的(命名)文件。
到目前为止,我已经:
mkfifo importlog.txt; cat - > importlog.txt & zip --password testpass - --fifo importlog.txt; rm importlog.txt;
当我使用cat -
替换echo "content"
时,此方法正常,但在cat -
就位时,会创建一个带有空的importlog.txt的zip文件。我的偏好实际上是流式传输内容,因为它会非常多。
我认为我的问题是如何将stdin流式传输到第二个命令,但我很可能忽略了另一个解决方案。我试图用proc_open
和fwrite。
答案 0 :(得分:1)
我认为不可能将此解决为单行bash代码。我最终编写了一个更大的php函数,通过命名管道传输内容。
function createSingleFileZipArchive($filename, $contents, $password = null){
$filename = (string) $filename;
if(mb_strlen(trim($filename)) === 0){
throw new LengthException('Filename empty');
}
//create subfolder in tempdir containing process id to prevent concurrency issues
$tempDir = sys_get_temp_dir().'/phpzip-'.getmypid();
if(!is_dir($tempDir)){
mkdir($tempDir);
}
//create FIFO and start zip process that reads fifo stream
$madeFifo = posix_mkfifo($tempDir.'/'.$filename, 0600);
if($madeFifo === false){
throw new RuntimeException('failed to create fifo to stream data to zip process.');
}
$proc = proc_open('cd '.$tempDir.'; zip'.($password === null ? null : ' --password '.escapeshellarg($password)).' - --fifo '.escapeshellarg($filename), [['pipe', 'r'],['pipe', 'w'],['pipe', 'w']], $pipes);
if($proc === false){
throw new RuntimeException('failed to start zip-process');
}
//write to fifo
$in = fopen($tempDir.'/'.$filename, 'w'); //always open fifo writer after reader is opened, otherwise process will lock
fwrite($in, $contents);
fclose($in);
//get output before reading errors.
//If no errors/debug output was generated the process could otherwise hang.
$output = stream_get_contents($pipes[1]);
//check if any errors occurred
if ($err = stream_get_contents($pipes[2])) {
$errorOutput = [];
foreach(explode($err,PHP_EOL) as $errLine){
$errLine = trim($errLine);
if(strlen($errLine) > 0 && strpos($errLine, 'Reading FIFO') === false && strpos($errLine, 'adding:') === false){ //ignore default notices.
$errorOutput[] = trim($errLine);
}
}
if(count($errorOutput) > 0){
throw new RuntimeException("zip-error: ".implode('; ',$errorOutput));
}
}
//cleanup
foreach($pipes as $pipe){
fclose($pipe);
}
proc_close($proc);
unlink($tempDir.'/'.$filename);
rmdir($tempDir);
//done
return $output;
}
file_put_contents('importlog.zip',createSingleFileZipArchive('importlog.txt','test contents','testpass'));