在POSIX系统上,是否始终可用wget或类似的程序?

23

是否有类似 wget/lynx/GET 的 HTTP 客户端,在 POSIX 或 *nix 操作系统中默认分发,并可用于最大程度的可移植性?

我知道大多数系统都安装了 wgetlynx,但是我记得使用默认设置安装一些 Ubuntu 服务器系统时,基础包中没有安装它们两个。

我正在为 Linux(可能还包括 Mac)编写一个 shell 脚本,以在计算机上安装软件。为了避免必须分发几个大文件,我想从互联网上获取这些文件,而不是将其打包到安装程序中。目前,安装脚本要通过Makeself创建成一个单一的文件进行分发。

我希望避免安装脚本超过100MB, 如果这些文件包含进去, 而且如果人们正在升级或重新安装软件,则可能不需要这些文件。也许最具可移植性的方法是将文件包含在软件包中。

目前,我只是考虑让脚本按照顺序检查是否有wgetlynxGET,并使用其中任何一个来下载,但如果有一种方法可以在所有系统上运行,则可以完全避免这种情况。

编辑:

是否有人了解 lwp-request (GET) 及其可用性?这似乎在我检查过的几个系统中都很容易获得,并且我记得在10多年前追溯到 RedHat 时它就已经存在了。


1
你也可以使用curl或(极端的例子)netcat(通常别名为nc)。但是,我认为wget应该是最普遍可用的。如果这个不可用,那么其他所有选项的可能性都不会好到哪里去。 - Niklas B.
真的,curl 也是一种可能性,不过我认为它比 wget 更不常见。我没有考虑到 nc,所以那也是一种可能性,我知道它已经存在很长时间了。 - drew010
4
顺便提一句,你也可以使用bash本身来发起HTTP请求。我猜bash比wget更常见(尽管该特定功能可能并不常见启用)。 - Niklas B.
Bash中的/dev/tcp是个很酷的发现。如果你想回答关于nc和bash技巧的问题,我可能会接受。我开始觉得也许我在过度分析这个特定的部分,最坏的情况下可以告诉他们安装其中一个软件包。 - drew010
我已经做了,但sarnold的回答更详细一些 :) - Niklas B.
3
因为你提到了 Mac:OS X 自带 curl(和 ftp、sftp、nc,当然还有 bash),但没有 wget。 - Gordon Davisson
6个回答

17

我建议使用rsync通过ssh传输你的文件。虽然rsync的界面看起来可能有些压抑,但大多数用户可以选择rsync -avzP,如果需要更多灵活性,rsync可以适应。使用ssh将为您的连接提供完整性、真实性和隐私。

curl是http传输的事实标准;如果首选纯http或https,则curl或基于curl的工具可能是一个不错的选择。


根据我的经验,可用的工具按以下顺序:

  • wget
  • curl
  • sftp
  • ftp
  • GET(我经常使用HEAD,经常忘记它只是套装中的一个工具)
  • tftp
  • nc(我希望它比我用得更多)
  • socat(甚至更少见)

bash/dev/tcp工具在我使用的大多数系统上都可用(一些使用dashpdksh),但是使用bashncsocatecho是通过最长路径访问HTTP的方式,你必须以某种方式处理头部,这降低了它的优雅度。


许多 ftp 客户端,如 ncftplftp 等,可能会或可能不会安装 ftp 符号链接;派生自 Debian 的系统至少会使用系统首选的 ftp 客户端填充 /etc/alternatives/ftp,而 /usr/bin/ftp 将指向该客户端。 - sarnold
1
我发现wget在我使用的大多数系统上都可用,但curl通常是我手动编译的东西。然而,相比之下,由于SFTP基于具有SSH访问权限,我发现它通常也总是可用的。因此,我会将其排名较高。 - Mark D
@sarnold 如果您能提供一些关于您的经验样本所涉及的操作系统类型的线索,那将会很有帮助。我想大部分可能是Unix和Linux系统?但我刚刚注意到,在我的MacBook上,安装了curl但没有wget,这可能表明这对于macOS用户来说是典型的,如果包括了Mac世界(比Linux世界大得多),那么您的列表将会有很大不同。当然,这里大部分只是猜测细节。另外,我刚刚注意到您的答案是2012年的,所以无论您在这里说什么,我都不应该把它放在心上 :-) - Don Hatch
@DonHatch,感谢提醒。我会稍微更新一下这个答案。 - sarnold

11

POSIX 7工具官方列表

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html

以下内容不包括在列表中:

  • wget
  • curl
  • ftp

LSB 也是如此,基本上只保证了POSIX实用程序。

但我认为POSIX C足以实现大多数netcat的功能,所以这确实是一个错失的机会。例如:如何在没有libcurl的情况下使用C进行HTTP get请求?

可能是因为像HTTP这样的网络协议在POSIX仍在发展时被认为过于特定/不存在,而POSIX基本上永久冻结。值得注意的是,HTTPS加密可能不容易实现。


3

3

Curl可能比wget更常见。至少在我的经验中,因为更多的其他工具依赖于它。但是curl和wget都是超级简单的安装,并且在任何系统上都可以使用。


我同意,但是当涉及到预装在系统上时,我认为它不是常见的“开箱即用”安装方式。特别是当我们谈论5年以上的Linux发行版时。 - drew010
你说得对,我不知道自己在想什么。我认为它不会运行在那么老的设备上。感谢您的评论。 - drew010
1
举个例子,Debian(Stretch)预装了wget,但没有curl(我怀疑2012年也不会有)。根据我的经验,wget比curl更常见(我希望情况不同)。 - JepZ
1
@JepZ,我不确定“根据我的经验,wget比curl更常用”是否有什么意义,除了表达你所处的子文化 :-) 我这么说是因为我发现,尽管我的基于Ubuntu的Linux机器上安装了wget(而非curl),但在我的Macbook上安装了curl(而非wget)。我猜后者意味着大多数人在Mac世界中(这个世界比Linux世界还要大)会说:“根据我的经验,curl比wget更常用”。 - Don Hatch
@DonHatch 你可能是正确的,这取决于子文化。在我写下那条评论几天后,我也看到了 macOS 上的情况,感到非常惊讶。而且确实如此,最近我没有经常在发行版之间切换,所以即使 15 年前 curl 在默认安装中有点罕见,这种情况也可能已经改变了。 - JepZ

1

我建议使用ftp或wget,因为它们在Linux发行版中最常见。最佳实践可能是让您的脚本查看命令是否可用,如果不可用则转到下一个命令。


1

现成(自动检测)脚本

我编写了一个符合Posix标准的Shell函数,也可以用作命令:

http_get

#!/bin/sh
## Usage: http_get <url> [filepath]
## Copyright (C) 2022 AJ ONeal <aj@therootcompany.com>
## Permission to copy and modify is granted under the CC0-1.0 license
set -e
set -u

http_get() { (
    http_get_url="${1}"
    http_get_filepath="${2:-"$(basename "${http_get_url}")"}"
    if [ -z "${http_get_url}" ]; then
        echo >&2 "Usage: http_get <url> [filepath]"
        return 1
    fi

    if command -v wget > /dev/null; then
        # wget supports resumable downloads
        if ! wget -q -c "${http_get_url}" -O "${http_get_filepath}.part"; then
            echo >&2 "failed to download ${http_get_url} to ${http_get_filepath}.part"
            return 1
        fi
    elif command -v curl > /dev/null; then
        if ! curl -fsSL "${http_get_url}" -o "${http_get_filepath}.part"; then
            echo >&2 "failed to download ${http_get_url} to ${http_get_filepath}.part"
            return 1
        fi
    fi

    # move downloaded file into file location
    mv "${http_get_filepath}.part" "${http_get_filepath}"
); }

http_get "${1:-}" "${2:-}"

好处

  • 安全可靠,适用于命令或source函数使用(子shell中的变量和命名空间)
  • 在“严格模式”下运行(出现错误时干净退出)
  • shellcheck检查通过(符合Posix标准,没有bash特有语法)
  • 适用于批处理模式(静音进度条)
  • 适用于部分和可恢复下载(优先使用wget

额外功能

还有一个扩展版本,可以检测shell是否为交互式(以启用进度条),请访问https://therootcompany.com/blog//posix-shell-http-request-curl-vs-wget/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接