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

3

我正在尝试弄清楚使用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/*

这是理想化的流程吗?我是否有所改进的余地?

1
请注意,此处将安装到 /opt/nginx/nginx,并将前缀设置为 /opt/nginx - zero2cx
2个回答

5
首先,您似乎正在重复造轮子:如果您要解决的问题是在目标系统上自动打包/构建软件,则有无数解决方案可用,以各种软件包管理系统、端口构建器等形式存在。
至于您的shell脚本,有几件事情需要考虑修复:
  • Stuff like http://nginx.org/download/nginx-1.3.6.tar.gz or nginx-1.3.6.tar.gz are constants. Try to extract all constants in separate variables and use them to make maintaining this script a little bit easier, for example:

    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"
    
  • You generally can't be 100% sure that wget exists on target deployment system. If you want to maximize portability, you can try to detect popular networking utilities, such as wget, curl, fetch or even lynx, links, w3m, etc.

  • Proper practices on using a temporary directory is a long separate question, but, generally, you'll need to adhere to 3 things:

    • One should somehow find out the temporary directory location. Generally, it's wrong to assume that /tmp is always a temporary directory, as it can be not mounted, it can be non-writable, if can be tmpfs filesystem which is full, etc, etc. Unfortunately, there's no portable and universal way to detect what temporary directory is. The very least one should do is to check out contents of $TMPDIR to make it possible for a user to point the script to proper temporary dir. Another possibly bright idea is a set of heuristic checks to make sure that it's possible to write to desired location (checking at least $TMPDIR, $HOME/tmp, /tmp, /var/tmp), there's decent amount of space available, etc.
    • One should create a temporary directory in a safe manner. On Linux systems, mktemp --tmpdir -d some-unique-identifier.XXXXXXXXX is usually enough. On BSD-based systems, much more manual work needed, as default mktemp implementation is not particularly race-resistant.
    • One should clean up temporary directory after use. Cleaning should be done not only on a successful exit, but also in a case of failure. This can be remedied with using a signal trap and a special cleanup callback, for example:

      # 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
      
  • If you really want to use recursive rm, then using any * to glob files is a bad practice. If your directory would have more than several thousands of files, * would expand to too much arguments and overflow shell's command line buffer. I might even say that using any globbing without a good excuse is generally a bad practice. The rm line above should be rewritten at least as:

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

    Removing all subdirectories in /tmp (as in /tmp/*) is a very bad practice on a multi-user system, as you'll either get permission errors (you won't be able to remove other users' files) or you'll potentially heavily disrupt other people's work by removing actively used temporary files.

  • Some minor polishing:

    • POSIX-standard tar uses normal short UNIX options nowadays, i.e. tar -xvz, not tar xvz.
    • Modern GNU tar (and, AFAIR, BSD tar too) doesn't really need any of "uncompression" flags, such as -z, -j, -y, etc. It detects archive/compression format itself and tar -xf is sufficient to extract any of .tar / .tar.gz / .tar.bz2 tarballs.

1
谢谢,经过这么多年这仍然是最佳的答案。 - Daniel Braun
我在SO上遇到的最有价值的答案之一,令人难以置信的是这个问题的流量如此之低...这里有很多好的信息! - Jesse Nickles

1

这就是基本思路。您需要以root身份运行make install命令(或整个脚本,如果您想要)。您的rm -r /tmp/*应该改为rm -r /tmp/nginx,因为其他命令可能在tmp目录中有正在处理的内容。

还应该注意到,从源代码构建像这样的项目而不进行任何修改的机会相当低。通常情况下,您会发现需要明确指定库的路径,或者某些代码在您的发行版上无法正确编译。


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