【问题标题】:How to properly make path handling robust in a bash program?如何在 bash 程序中正确地使路径处理变得健壮?
【发布时间】:2010-12-04 22:32:25
【问题描述】:
  • 脚本有一些硬编码的相对路径。我希望它们与脚本位置相关。

  • 脚本需要更改当前目录,因为其他程序 (cmake) 需要它。

  • 脚本将一些(可能相对于调用者的)路径作为参数,并将它们传递给该程序,它们应该被去相对化。

问题是内联的:

#!/bin/sh

# First arg should be Release or Debug    
# TODO test for that.

if test -n "$1"; then          # BTW how to test whether $1 is Debug or Release?
  BUILD_TYPE="$1"
else
  BUILD_TYPE="Release"
fi

# Set install prefix to current directory, unless second argument is given. 

if test -n "$2"; then
  INSTALL_PREFIX="$2"    # How to derelativize this path argument?
else
  INSTALL_PREFIX=bin     # How to make this path relative to script location?
fi

# Make build directory and do cmake, make, make install.

mkdir -p build/${BUILD_TYPE} && # How to make this path relative to script location?
cd build/${BUILD_TYPE} &&

cmake -D CMAKE_BUILD_TYPE=${BUILD_TYPE} \
      -D CMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \ # Possible relative to caller current directory. 
      ../../ &&             # Relative to scrip position.
make -j4 &&
make install

这是一个常见问题还是我以非标准方式做某事?

【问题讨论】:

  • 我不要求你重新制作脚本,我只需要一个指导如何以正确的方式去做。

标签: bash path relative-path


【解决方案1】:

1)

test $1 == "Debug"

2) 放

SCRIPT_DIR="$(dirname $0)"
ORIGINAL_DIR="$(pwd)"

在脚本的顶部(#! 行之后的第一个非注释行)

使变量相对于脚本成为绝对变量:

[ "${VAR/#\//}" != "$VAR" ] || VAR="$SCRIPT_DIR/$VAR"

使其相对于起始目录:

[ "${VAR/#\//}" != "$VAR" ] || VAR="$ORIGINAL_DIR/$VAR"

基本上,我们用空的"${VAR/#\//}" 替换前导斜杠并与"$VAR" 进行比较,如果它们不同,则$VAR 是绝对的。否则,我们会在前面添加一个我们希望使其成为绝对目录的目录。

【讨论】:

  • 我找到了 readlink -f 命令,但我不确定它是否有帮助。你能评论一下吗?
  • readlink -f 处理符号链接,而不是使路径成为绝对路径。您不需要规范化您给出的路径,因为您可以通过符号链接阅读。
  • ./ 是一个相对路径,并被这样对待。程序读取包含 /./ 的路径不会导致任何问题,尽管您可能希望在向用户显示路径之前进行整理。
【解决方案2】:

除了Douglas Leeder 所说的之外,我建议始终用双引号将您的变量括起来,以防止带有空格字符的路径弄乱您的脚本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 2010-12-04
    • 1970-01-01
    • 2014-06-07
    • 2011-07-21
    相关资源
    最近更新 更多