【问题标题】:Check If Shell Script $1 Is Absolute Or Relative Path [duplicate]检查 Shell 脚本 $1 是绝对路径还是相对路径 [重复]
【发布时间】:2013-12-10 20:56:30
【问题描述】:

正如标题所说,我正在尝试确定我的 bash 脚本是否接收到目录的完整路径或相对文件作为参数。

由于某些原因,以下似乎对我不起作用:

#!/bin/bash

DIR=$1

if [ "$DIR" = /* ]
then
    echo "absolute"
else
    echo "relative"
fi

当我使用完整路径或绝对路径运行脚本时,它会显示:

./script.sh: line 5: [: too many arguments
relative

由于某些原因,我似乎无法弄清楚这个错误。有什么想法吗?

【问题讨论】:

    标签: bash shell


    【解决方案1】:

    [ ... ] 不进行模式匹配。 /* 正在扩展为 / 的内容,所以实际上你有

    if [ "$DIR" = /bin /boot /dev /etc /home /lib /media ... /usr /var ]
    

    或类似的东西。请改用[[ ... ]]

    if [[ "$DIR" = /* ]]; then
    

    为了符合 POSIX,或者如果您没有进行模式匹配的 [[,请使用 case 语句。

    case $DIR in
      /*) echo "absolute path" ;;
      *) echo "something else" ;;
    esac
    

    【讨论】:

    • 如果我给这个路径/home/user/folder1/../folder2 这是相对的,它会输出它是绝对的,这是错误的。
    • 相对路径是指不同文件的路径,具体取决于当前工作目录。该路径始终引用/home/user/folder2,因此它是绝对路径。 .. 不仅仅是一个 shell 快捷方式;对于它所在目录的父级,它是文件系统中一个非常真实的条目。
    • 显然这只适用于 bash,不适用于 (a)sh
    • 不,[[bash 和其他一些 shell 支持的扩展。我会在答案中添加一个符合 POSIX 标准的版本。
    【解决方案2】:

    只测试第一个字符:

    if [ "${DIR:0:1}" = "/" ]
    

    【讨论】:

    • bash(以及kshzsh)中运行良好,但只是为了避免潜在的混淆:尽管使用了[ ... ]=,但这个解决方案不是POSIX-兼容(POSIX shell 规范不支持位置子字符串提取)。如果不要求 POSIX 合规性,例如在这种情况下,通常最好使用[[ ... ]][[ "${DIR:0:1}" == '/' ]](甚至[[ ${DIR:0:1} == '/' ]])。
    【解决方案3】:

    另一种情况是从~(波浪号)开始的路径。 ~user/some.file~/some.file 是某种绝对路径。

    if [[ "${dir:0:1}" == / || "${dir:0:2}" == ~[/a-z] ]]
    then
        echo "Absolute"
    else
        echo "Relative"
    fi
    

    【讨论】:

      【解决方案4】:

      ShellCheck 自动指出“[ .. ] can't match globs. Use [[ .. ]] or grep.

      换句话说,使用

      if [[ "$DIR" = /* ]]
      

      这是因为[是一个常规命令,所以/*被shell事先扩展,变成了

      [ "$DIR" = /bin /dev /etc /home .. ]
      

      [[是shell专门处理的,不存在这个问题。

      【讨论】:

        【解决方案5】:

        编写测试很有趣:

        #!/bin/bash
        
        declare -a MY_ARRAY # declare an indexed array variable
        
        MY_ARRAY[0]="/a/b"
        MY_ARRAY[1]="a/b"
        MY_ARRAY[2]="/a a/b"
        MY_ARRAY[3]="a a/b"
        MY_ARRAY[4]="/*"
        
        
        # Note that 
        # 1) quotes around MY_PATH in the [[ ]] test are not needed
        # 2) the expanded array expression "${MY_ARRAY[@]}" does need the quotes
        #    otherwise paths containing spaces will fall apart into separate elements.
        # Nasty, nasty syntax.
        
        echo "Test with == /* (correct, regular expression match according to the Pattern Matching section of the bash man page)"
        
        for MY_PATH in "${MY_ARRAY[@]}"; do
           # This works
           if [[ $MY_PATH == /* ]]; then
              echo "'$MY_PATH' is absolute"
           else
              echo "'$MY_PATH' is relative"
           fi
        done
        
        echo "Test with == \"/*\" (wrong, becomes string comparison)"
        
        for MY_PATH in "${MY_ARRAY[@]}"; do
           # This does not work at all; comparison with the string "/*" occurs!
           if [[ $MY_PATH == "/*" ]]; then
              echo "'$MY_PATH' is absolute"
           else
              echo "'$MY_PATH' is relative"
           fi
        done
        
        echo "Test with = /* (also correct, same as ==)"
        
        for MY_PATH in "${MY_ARRAY[@]}"; do
           if [[ $MY_PATH = /* ]]; then
              echo "'$MY_PATH' is absolute"
           else
              echo "'$MY_PATH' is relative"
           fi
        done
        
        echo "Test with =~ /.* (pattern matching according to the regex(7) page)"
        
        # Again, do not quote the regex; '^/' would do too
        
        for MY_PATH in "${MY_ARRAY[@]}"; do
           if [[ $MY_PATH =~ ^/[:print:]* ]]; then
              echo "'$MY_PATH' is absolute"
           else
              echo "'$MY_PATH' is relative"
           fi
        done
        

        【讨论】:

        • 测试~/a/b路径怎么样?
        猜你喜欢
        • 2011-11-25
        • 2014-03-09
        • 2011-10-16
        • 2015-11-13
        • 2019-09-09
        • 1970-01-01
        • 2018-09-17
        • 1970-01-01
        • 2012-07-09
        相关资源
        最近更新 更多