用 python 封装 bash 脚本

kst*_*tis 0 python bash shell subprocess wrapper

我刚刚找到了这个很棒的 wget 包装器,我想使用 subprocess 模块将其重写为 python 脚本。然而,事实证明这很棘手,给了我各种各样的错误。

download()
{
    local url=$1
    echo -n "    "
    wget --progress=dot $url 2>&1 | grep --line-buffered "%" | \
    sed -u -e "s,\.,,g" | awk '{printf("\b\b\b\b%4s", $2)}'

    echo -ne "\b\b\b\b"
    echo " DONE"
}
Run Code Online (Sandbox Code Playgroud)

然后可以这样调用:

file="patch-2.6.37.gz"
echo -n "Downloading $file:"
download "http://www.kernel.org/pub/linux/kernel/v2.6/$file"
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

来源: http: //fitnr.com/showing-file-download-progress-using-wget.html

Tim*_*rce 5

我想你已经不远了。我主要想知道,为什么要费心运行管道,并且grep当你可以在Python内部完成所有这些工作时?sedawk

#! /usr/bin/env python

import re
import subprocess

TARGET_FILE = "linux-2.6.0.tar.xz"
TARGET_LINK = "http://www.kernel.org/pub/linux/kernel/v2.6/%s" % TARGET_FILE

wgetExecutable = '/usr/bin/wget'
wgetParameters = ['--progress=dot', TARGET_LINK]

wgetPopen = subprocess.Popen([wgetExecutable] + wgetParameters,
                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

for line in iter(wgetPopen.stdout.readline, b''):
    match = re.search(r'\d+%', line)
    if match:
        print '\b\b\b\b' + match.group(0),

wgetPopen.stdout.close()
wgetPopen.wait()
Run Code Online (Sandbox Code Playgroud)

  • +1。`wgetPopen.stdout` 可能会被破坏(我预计如此,但我不知道)。与普通文件一样,最好显式关闭它们(对文件使用“with”语句),而不依赖垃圾收集(这很复杂且难以推理)。`if not obj` 表示“如果 obj 为空或零”(对 `None` 的测试应写为 `if obj is None`),而不考虑类型,例如,在 Python 3 中 `pipe.readline()` 可能返回 ` b''` 或 '''` 是不同类型,而 `if not line` 对两者都适用。它支持来自同一来源的 Python 2/3。 (2认同)