2

我正在尝试制定使用 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/*

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

4

2 回答 2

4

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

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

  • 类似http://nginx.org/download/nginx-1.3.6.tar.gzor的东西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"
    
  • 您通常不能 100% 确定目标部署系统上存在 wget。如果您想最大限度地提高可移植性,您可以尝试检测流行的网络实用程序,例如wget, curl,fetch甚至lynx, links,w3m等。

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

    • 应该以某种方式找出临时目录位置。一般来说,假设它/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
      
  • 如果您真的想使用 recursive rm,那么使用 any *to glob 文件是一种不好的做法。如果您的目录将有超过数千个文件,*则会扩展为过多的参数并溢出 shell 的命令行缓冲区。我什至可以说,在没有好的借口的情况下使用任何通配符通常是一种不好的做法。上面的 rm 行至少应该重写为:

    rm -f /tmp/nginx-1.3.6.tar.gz
    rm -rf /tmp/nginx
    

    /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
于 2012-10-02T23:15:05.307 回答
1

这是基本的想法。您必须以 root 身份运行 make install 命令(或者如果需要,可以运行整个脚本)。你rm -r /tmp/*应该是rm -r /tmp/nginx因为其他命令可能在 tmp 目录中有他们正在处理的东西。

还应该注意的是,对于一个体面的项目,从源代码构建无需修改即可工作的可能性相当低。通常,您会发现您需要明确指定库的路径,否则某些代码在您的发行版上编译不正确。

于 2012-09-30T19:57:57.850 回答