使用 wget 使用临时目录下载和安装的理想方法?

J.Z*_*Zil 3 linux shell wget

我正在尝试找出使用 Wget 安装的正确过程,在本例中我将使用 Nginx。

# Download nginx to /tmp/ directory
wget http://nginx.org/download/nginx-1.3.6.tar.gz -r -P /tmp

# Extract nginx into /tmp/nginx directory
tar xzf nginx-1.3.6.tar.gz -C /tmp/nginx

# Configure it to be installed in opt
./configure --prefix=/opt/nginx

# Make it
make

# Make install
make install

# Clean up temp folder
rm -r /tmp/*
Run Code Online (Sandbox Code Playgroud)

这是理想化的过程吗?有什么我可以改进的地方吗?

Gre*_*Cat 5

首先,您似乎肯定是在重新发明轮子:如果您想要解决的问题是在目标系统上自动打包/构建软件,那么有无数的解决方案可用,以各种包管理系统、端口构建器等形式。

至于您的 shell 脚本,您应该考虑修复以下几件事:

  • http://nginx.org/download/nginx-1.3.6.tar.gz像or 这样的东西nginx-1.3.6.tar.gz是常数。尝试将所有常量提取到单独的变量中,并使用它们使维护此脚本变得更容易,例如:

    NAME=nginx
    VERSION=1.3.6
    FILENAME=$NAME-$VERSION.tar.gz
    URL=http://nginx.org/download/$FILENAME
    TMP_DIR=/tmp
    INSTALL_PREFIX=/opt
    
    wget "$URL" -r -P "$TMP_DIR"
    tar xzf "$FILENAME" -C "$TMP_DIR/nginx"
    
    Run Code Online (Sandbox Code Playgroud)
  • 您通常无法 100% 确定目标部署系统上存在 wget。如果您想最大限度地提高可移植性,您可以尝试检测流行的网络实用程序,例如wgetcurlfetch甚至lynxlinksw3m等。

  • 使用临时目录的正确做法是一个很长的单独问题,但是通常,您需要遵守三件事:

    • 人们应该以某种方式找出临时目录位置。一般来说,假设它/tmp总是一个临时目录是错误的,因为它可以不被安装,它可以是不可写的,如果可以是tmpfs已满的文件系统等等。不幸的是,没有可移植和通用的方法来检测什么临时目录是。至少应该做的是检查 的内容,$TMPDIR以便用户可以将脚本指向正确的临时目录。另一个可能的好主意是一组启发式检查,以确保可以写入所需的位置(至少检查$TMPDIR, $HOME/tmp, /tmp, /var/tmp),有足够的可用空间等。
    • 人们应该以一种安全的方式创建一个临时目录。在 Linux 系统上,mktemp --tmpdir -d some-unique-identifier.XXXXXXXXX通常就足够了。在基于 BSD 的系统上,需要更多的手动工作,因为默认mktemp实现并不是特别具有抗竞争性。
    • 使用后应清理临时目录。不仅在成功退出时需要进行清洁,而且在失败时也应该进行清洁。这可以通过使用信号陷阱和特殊的清理回调来解决,例如:

      # Cleanup: remove temporary files
      cleanup()
      {
              local rc=$?
              trap - EXIT
      
              # Generally, it's the best to remove only the files that we
              # know that we have created ourselves. Removal using recursive
              # rm is not really safe.
              rm -f "$LOCAL_TMP/some-file-we-had-created"
              [ -d "$LOCAL_TMP" ] && rmdir "$LOCAL_TMP"
      
              exit $rc
      }
      trap cleanup HUP PIPE INT QUIT TERM EXIT
      
      # Create a local temporary directory
      LOCAL_TMP=$(mktemp --tmpdir -d some-unique-identifier.XXXXXXXXX)
      
      # Use $LOCAL_TMP here
      
      Run Code Online (Sandbox Code Playgroud)
  • 如果您确实想使用 recursive rm,那么使用 any*来 glob 文件是一个不好的做法。如果您的目录包含超过数千个文件,*则会扩展为太多参数并溢出 shell 的命令行缓冲区。我什至可能会说,在没有好的借口的情况下使用任何通配符通常是一种不好的做法。上面的 rm 行至少应该重写为:

    rm -f /tmp/nginx-1.3.6.tar.gz
    rm -rf /tmp/nginx
    
    Run Code Online (Sandbox Code Playgroud)

    /tmp在多用户系统上删除(如)中的所有子目录/tmp/*是一种非常糟糕的做法,因为您要么会收到权限错误(您将无法删除其他用户的文件),要么可能会严重破坏其他用户的文件。通过删除经常使用的临时文件来完成人们的工作。

  • 一些细微的抛光:

    • 如今, POSIX 标准tar使用普通的短 UNIX 选项,即tar -xvz,而不是tar xvz
    • 现代GNU tar(以及 AFAIR、BSD tar)实际上并不需要任何“解压缩”标志,例如-z-j-y等。它会检测存档/压缩格式本身,并且tar -xf足以提取任何.tar// tarball。.tar.gz.tar.bz2