如何使用PHP在远程服务器批量解压多个.tar文件?
Got it, let's fix up your script to handle multiple .tar files smoothly. The main issue with your original single-file approach is that tar doesn't accept multiple archive files in one -xvf call by default—we need to adjust the command logic to process each file individually or use a shell-based batch method. Here are two reliable approaches:
Approach 1: Extract All .tar Files in a Target Directory
If you want to unpack every .tar file in /tmp/test/, use a shell loop or find command to iterate through each file. This is great for bulk operations:
<?php $server = "host"; $username = "usr"; $password = "pass"; // Shell loop to process all .tar files (avoids errors if no archives exist) $command = 'for file in /tmp/test/*.tar; do if [ -f "$file" ]; then tar -xvf "$file" -C /tmp/test/ # -C sets the extraction directory (optional) fi done'; // Add basic error checking for connection $connection = ssh2_connect($server, 22); if (!$connection) { die("Failed to connect to $server on port 22"); } // Verify authentication if (!ssh2_auth_password($connection, $username, $password)) { die("Failed to authenticate with username: $username"); } // Execute command and capture output/errors for debugging $stream = ssh2_exec($connection, $command); $stderr_stream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR); stream_set_blocking($stream, true); stream_set_blocking($stderr_stream, true); $output = stream_get_contents($stream); $error = stream_get_contents($stderr_stream); echo "Extraction Output:\n$output\n"; echo "Error Log:\n$error\n"; // Clean up streams fclose($stream); fclose($stderr_stream); ?>
If you need to include subdirectories in your search, swap the command with this find version:
$command = 'find /tmp/test -type f -name "*.tar" -exec tar -xvf {} -C /tmp/test/ \;';
Approach 2: Extract a Specific List of .tar Files
If you have a predefined set of archives to unpack, loop through them directly in PHP and run the tar command for each one:
<?php $server = "host"; $username = "usr"; $password = "pass"; $targetDir = "/tmp/test/"; // Your custom list of .tar files $tarFiles = [ "OK_MemExpFile_UPA_519_99_1_2509_20180403135101.tar", "another_archive.tar", "third_file.tar" ]; $connection = ssh2_connect($server, 22); if (!$connection) die("Connection to remote server failed"); if (!ssh2_auth_password($connection, $username, $password)) die("Authentication failed"); foreach ($tarFiles as $file) { // Escape file paths to prevent shell injection risks $safeFilePath = escapeshellarg($targetDir . $file); $command = "tar -xvf $safeFilePath -C $targetDir"; $stream = ssh2_exec($connection, $command); $stderr = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR); stream_set_blocking($stream, true); stream_set_blocking($stderr, true); echo "Processing $file:\n"; echo "Output: " . stream_get_contents($stream) . "\n"; echo "Errors: " . stream_get_contents($stderr) . "\n\n"; fclose($stream); fclose($stderr); } ssh2_disconnect($connection); ?>
Critical Tips to Avoid Issues:
- Shell Injection Protection: Always use
escapeshellarg()when passing file paths with spaces or special characters to prevent malicious input risks. - Error Debugging: The original script didn't check for connection/auth failures or capture stderr—adding these helps you fix issues like permission errors or corrupted archives.
- Extraction Control: Use the
-Cflag withtarto specify exactly where files are extracted, so you don't end up with files scattered in unexpected directories. - Empty Archive Check: The
if [ -f "$file" ]line in the shell loop prevents errors if there are no.tarfiles in the target directory.
内容的提问来源于stack exchange,提问作者Stevanus Prasetyo

