как быть уверенным, что два каталога не являются подкаталогами друг другу (BASH) - PullRequest
4 голосов
/ 14 июля 2011

РЕДАКТИРОВАНИЕ: это более или менее то, что я придумал после хорошего ввода @ Mechanical. Любое понимание?

#!/bin/bash

path1="$(readlink -e "$1")"
path2="$(readlink -e "$2")"

EBADARGS=65

function checkArgsNumber()
{
    if test "$#" -ne 2; then
        echo "ERRORE: this script takes exactly 2 params."  
        exit $EBADARGS
    fi
}

function checkExistence()
{
    if [ ! -d $path1 ]; then
        echo  "ERROR: "$1" does not exist"
        exit $EBADARGS
    elif [ ! -d "$2" ]; then
        echo  "ERROR: "$2" does not exist"
        exit $EBADARGS
    elif [[ -L $path1 ]]; then
        echo "ERROR: path1 can't be a symbolic link"
        exit $EBADARGS
    elif [[ -L $2 ]]; then
        echo "ERROR: path2 can't be a symbolic  link"
        exit $EBADARGS
    fi
}

function checkIfSame()
{
    if [[ $path1 == $path2 ]]; then
        echo "ERROR: path1 and path2 must be different directories"
        exit $EBADARGS     
    fi   
}

function checkIfSubdirectories()
{
    if [[ $path1 = *$path2* ]]; then
        echo "ERROR:"$1" is a $path2 subdirectory"
        exit $EBADARGS
    elif [[ $path2 = *$path1* ]]; then
        echo "ERROR:"$2" is a  $path1 subdirectory"
        exit $EBADARGS
    elif [[ -e "$(find $path1 -samefile $path2)" ]]; then
        echo "ERROR:"$(find $path1 -samefile $path2 -print0)" and "$2" have the same inode, $path2 is a  $path1 subdirectory"
        exit $EBADARGS
    elif [[ -e "$(find $path2 -samefile $path1)" ]]; then
        echo "ERROR:"$(find $path2 -samefile $path1 -print0)" and "$2" have the same inode,  $path1 is a  $path2 subdirectory"
        exit $EBADARGS
    fi
}

checkArgsNumber "$@"
checkExistence "$@"
checkIfSame "$@"
checkIfSubdirectories "$@"

сейчас .. это должно работать, и я надеюсь, что это как-то полезно. Может кто-нибудь объяснить мне, как работает *$path2* часть? Как называется этот оператор * *? Куда мне идти читать об этом?

1 Ответ

2 голосов
/ 14 июля 2011

Некоторые проблемы:

Стилистические

Вы, вероятно, должны заключить весь аргумент в echo, как

    echo "ERROR: $1 is a subdirectory of $(readlink -e "$2")"

Без кавычек вокруг аргумента echo, вы технически передаете каждое слово как его собственный параметр: echo "ERROR:somedir" "is" "a" "subdirectory" .... Поскольку echo выводит свои параметры в заданном порядке, разделенных пробелами, вывод то же самое в вашем случае. Но семантически это не то, что вы хотите.

(Пример, где все будет иначе:

echo foo          bar

напечатает foo bar.)

Сообщение об ошибке не работает

Если аргументы не существуют

$ ./check.sh nonexistent1 nonexistent2
ERROR:nonexistent1 is a subdirectory of 

Очевидно, что это не имеет значения, если вы уже проверили, что они существуют.

Вам также необходимо проверить угловые случаи, например, когда параметры ссылаются на один и тот же каталог:

$ mkdir a b
$ ln -s ../a b/c
$ ./check.sh a b/c
ERROR:a is a subdirectory of /dev/shm/a

Не обнаруживает символические ссылки

$ mkdir a b
$ ln -s ../a b/c
$ ./check.sh a b

не выдает сообщение об ошибке.

Не обнаруживает mount --bind

$ mkdir a b b/c
$ sudo mount --bind a b/c
$ ./check.sh a b

не выдает сообщение об ошибке.

...