7z 压缩日志: pty 运行(非tty也输出banner) + 压缩完成日志(大小/压缩率/耗时)
This commit is contained in:
@@ -19,6 +19,7 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tarfile
|
import tarfile
|
||||||
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@@ -33,10 +34,35 @@ COMPRESS_SUFFIX = {".db", ".sqlite", ".sqlite3", ".sql", ".txt", ".json", ".xml"
|
|||||||
|
|
||||||
|
|
||||||
def _7z(args: list[str]) -> None:
|
def _7z(args: list[str]) -> None:
|
||||||
"""调系统 7z (p7zip-full), 实时透传进度输出 (7z 自带百分比进度条)"""
|
"""调系统 7z (p7zip-full), pty 运行保证百分比进度输出
|
||||||
r = subprocess.run(["7z"] + args)
|
|
||||||
if r.returncode != 0:
|
SSH/管道 (非 tty) 下 7z 默认不输出百分比进度条, pty 模拟终端
|
||||||
raise RuntimeError(f"7z 失败 (exit {r.returncode})")
|
让 7z 始终输出 0%..100% 实时进度, 透传到 stdout。
|
||||||
|
"""
|
||||||
|
import os as _os
|
||||||
|
import pty as _pty
|
||||||
|
cmd = ["7z"] + args
|
||||||
|
master, slave = _pty.openpty()
|
||||||
|
proc: subprocess.Popen | None = None
|
||||||
|
try:
|
||||||
|
proc = subprocess.Popen(cmd, stdout=slave, stderr=slave, close_fds=True)
|
||||||
|
_os.close(slave)
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
data = _os.read(master, 4096)
|
||||||
|
except OSError:
|
||||||
|
break
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
sys.stdout.write(data.decode(errors="replace"))
|
||||||
|
sys.stdout.flush()
|
||||||
|
proc.wait()
|
||||||
|
finally:
|
||||||
|
_os.close(master)
|
||||||
|
finally:
|
||||||
|
if proc is not None and proc.returncode != 0:
|
||||||
|
raise RuntimeError(f"7z 失败 (exit {proc.returncode})")
|
||||||
|
|
||||||
|
|
||||||
def _cfg() -> dict[str, Any]:
|
def _cfg() -> dict[str, Any]:
|
||||||
@@ -242,8 +268,14 @@ def backup(name: str, chunk_mb: int = 10) -> int:
|
|||||||
# 7z 压缩 (与上传文件一致): 含文本类 -mx=9, 照片视频 -mx=1
|
# 7z 压缩 (与上传文件一致): 含文本类 -mx=9, 照片视频 -mx=1
|
||||||
mx = 9 if any(_compress(f) for f in batch) else 1
|
mx = 9 if any(_compress(f) for f in batch) else 1
|
||||||
seven = tar_path.with_suffix(".tar.7z")
|
seven = tar_path.with_suffix(".tar.7z")
|
||||||
|
raw_mb = tar_path.stat().st_size / 1048576
|
||||||
print(f"[备份] 7z 压缩 (mx={mx}) ...")
|
print(f"[备份] 7z 压缩 (mx={mx}) ...")
|
||||||
|
_t0 = time.time()
|
||||||
_7z(["a", "-y", "-bd", f"-mx={mx}", str(seven), str(tar_path)])
|
_7z(["a", "-y", "-bd", f"-mx={mx}", str(seven), str(tar_path)])
|
||||||
|
_dt = time.time() - _t0
|
||||||
|
sz_mb = seven.stat().st_size / 1048576
|
||||||
|
print(f"[备份] 7z 压缩完成: {raw_mb:.1f} MB -> {sz_mb:.1f} MB "
|
||||||
|
f"(压缩率 {sz_mb / raw_mb * 100:.0f}%), 耗时 {_dt:.1f}s")
|
||||||
tar_path.unlink(missing_ok=True)
|
tar_path.unlink(missing_ok=True)
|
||||||
tar_path = seven
|
tar_path = seven
|
||||||
size_mb = tar_path.stat().st_size / 1048576
|
size_mb = tar_path.stat().st_size / 1048576
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ Package: 7z-encrypt-client
|
|||||||
Version: 1.0.0
|
Version: 1.0.0
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Maintainer: edgevoid <edgevoid@users.noreply.gitee.com>
|
Maintainer: edgevoid <edgevoid@users.noreply.gitee.com>
|
||||||
Installed-Size: 126
|
Installed-Size: 127
|
||||||
Depends: python3 (>= 3.10), python3-venv, p7zip-full
|
Depends: python3 (>= 3.10), python3-venv, p7zip-full
|
||||||
Section: utils
|
Section: utils
|
||||||
Priority: optional
|
Priority: optional
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
440c53f84f5722b5146959c8fc6d7a23 usr/bin/sz-config
|
440c53f84f5722b5146959c8fc6d7a23 usr/bin/sz-config
|
||||||
ec8cf0df841e479689ccb681f6168ccc usr/bin/sz-transfer
|
ec8cf0df841e479689ccb681f6168ccc usr/bin/sz-transfer
|
||||||
0ba5b8147990daa7fd07344952c42847 usr/bin/sz-tui
|
0ba5b8147990daa7fd07344952c42847 usr/bin/sz-tui
|
||||||
d0faeb4f34bb1cec041c9a4616e529be usr/share/7z-encrypt/backup.py
|
d94c79eeda7a87a620c1f24181e06359 usr/share/7z-encrypt/backup.py
|
||||||
dcb31e74e0a6ee8073337fc4fb2acf99 usr/share/7z-encrypt/config.py
|
dcb31e74e0a6ee8073337fc4fb2acf99 usr/share/7z-encrypt/config.py
|
||||||
8a064c0b3c21d50812a3fd69a320d862 usr/share/7z-encrypt/crypto.py
|
8a064c0b3c21d50812a3fd69a320d862 usr/share/7z-encrypt/crypto.py
|
||||||
21062e04f8c7f4471881a39c489dfa73 usr/share/7z-encrypt/metadata.py
|
21062e04f8c7f4471881a39c489dfa73 usr/share/7z-encrypt/metadata.py
|
||||||
|
|||||||
+36
-4
@@ -19,6 +19,7 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tarfile
|
import tarfile
|
||||||
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@@ -33,10 +34,35 @@ COMPRESS_SUFFIX = {".db", ".sqlite", ".sqlite3", ".sql", ".txt", ".json", ".xml"
|
|||||||
|
|
||||||
|
|
||||||
def _7z(args: list[str]) -> None:
|
def _7z(args: list[str]) -> None:
|
||||||
"""调系统 7z (p7zip-full), 实时透传进度输出 (7z 自带百分比进度条)"""
|
"""调系统 7z (p7zip-full), pty 运行保证百分比进度输出
|
||||||
r = subprocess.run(["7z"] + args)
|
|
||||||
if r.returncode != 0:
|
SSH/管道 (非 tty) 下 7z 默认不输出百分比进度条, pty 模拟终端
|
||||||
raise RuntimeError(f"7z 失败 (exit {r.returncode})")
|
让 7z 始终输出 0%..100% 实时进度, 透传到 stdout。
|
||||||
|
"""
|
||||||
|
import os as _os
|
||||||
|
import pty as _pty
|
||||||
|
cmd = ["7z"] + args
|
||||||
|
master, slave = _pty.openpty()
|
||||||
|
proc: subprocess.Popen | None = None
|
||||||
|
try:
|
||||||
|
proc = subprocess.Popen(cmd, stdout=slave, stderr=slave, close_fds=True)
|
||||||
|
_os.close(slave)
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
data = _os.read(master, 4096)
|
||||||
|
except OSError:
|
||||||
|
break
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
sys.stdout.write(data.decode(errors="replace"))
|
||||||
|
sys.stdout.flush()
|
||||||
|
proc.wait()
|
||||||
|
finally:
|
||||||
|
_os.close(master)
|
||||||
|
finally:
|
||||||
|
if proc is not None and proc.returncode != 0:
|
||||||
|
raise RuntimeError(f"7z 失败 (exit {proc.returncode})")
|
||||||
|
|
||||||
|
|
||||||
def _cfg() -> dict[str, Any]:
|
def _cfg() -> dict[str, Any]:
|
||||||
@@ -242,8 +268,14 @@ def backup(name: str, chunk_mb: int = 10) -> int:
|
|||||||
# 7z 压缩 (与上传文件一致): 含文本类 -mx=9, 照片视频 -mx=1
|
# 7z 压缩 (与上传文件一致): 含文本类 -mx=9, 照片视频 -mx=1
|
||||||
mx = 9 if any(_compress(f) for f in batch) else 1
|
mx = 9 if any(_compress(f) for f in batch) else 1
|
||||||
seven = tar_path.with_suffix(".tar.7z")
|
seven = tar_path.with_suffix(".tar.7z")
|
||||||
|
raw_mb = tar_path.stat().st_size / 1048576
|
||||||
print(f"[备份] 7z 压缩 (mx={mx}) ...")
|
print(f"[备份] 7z 压缩 (mx={mx}) ...")
|
||||||
|
_t0 = time.time()
|
||||||
_7z(["a", "-y", "-bd", f"-mx={mx}", str(seven), str(tar_path)])
|
_7z(["a", "-y", "-bd", f"-mx={mx}", str(seven), str(tar_path)])
|
||||||
|
_dt = time.time() - _t0
|
||||||
|
sz_mb = seven.stat().st_size / 1048576
|
||||||
|
print(f"[备份] 7z 压缩完成: {raw_mb:.1f} MB -> {sz_mb:.1f} MB "
|
||||||
|
f"(压缩率 {sz_mb / raw_mb * 100:.0f}%), 耗时 {_dt:.1f}s")
|
||||||
tar_path.unlink(missing_ok=True)
|
tar_path.unlink(missing_ok=True)
|
||||||
tar_path = seven
|
tar_path = seven
|
||||||
size_mb = tar_path.stat().st_size / 1048576
|
size_mb = tar_path.stat().st_size / 1048576
|
||||||
|
|||||||
Reference in New Issue
Block a user