1

В данном сценарии оболочки мне нужно взять известный путь и проверить его вверх (до корня файловой системы) для правильных разрешений. Как бы я разделил путь и пошел вверх по сценарию оболочки (может быть bash или "более низкий общий знаменатель")?

5 ответов5

1

Когда я попробовал awk-решение ennuikiller, оно пропустило текущий каталог для меня.

Итак, пока немного поздно, вот решение только для bash:

foo=`pwd`
while [ "$foo" != "" ]; do
    echo $foo # work with directory here
    foo=${foo%/*}
done

Не знаю, самое ли это элегантное решение, но оно работает. Я нашел простое объяснение манипуляции со строками в tldp и обернул вокруг него цикл.

1

Чтобы расширить решение ennuikiller:

realpath () {
    # realpath()        -- print absolute path (os.path.realpath) to $1
    #                      note: OSX does not have readlink -f
    python -c "import os,sys; print(os.path.realpath(os.path.expanduser(sys.argv[1])))" "${1}"
    return
}

walkpath () {
    # walkpath()        -- walk down path $1 and $cmd each component
    #   $1 : path (optional; default: pwd)
    #   $2 : cmd  (optional; default: ls -ald --color=auto)
    #https://superuser.com/a/65076 
    dir=${1:-$(pwd)}
    if [ $(uname) == "Darwin" ]; then
        cmd=${2:-"ls -ldaG"}
    else
        cmd=${2:-"ls -lda --color=auto"}
    fi
    dir=$(realpath ${dir})
    parts=$(echo ${dir} \
        | awk 'BEGIN{FS="/"}{for (i=1; i < NF+2; i++) print $i}')
    paths=('/')
    unset path
    for part in $parts; do
        path="$path/$part"
        paths=("${paths[@]}" $path)
    done
    ${cmd} ${paths[@]}
}
1

В Bash с путем, указанным в переменной оболочки (например, $ DIR), вы всегда можете получить последний (самый низкий) компонент пути, используя команду basename а оставшийся путь - с помощью команды dirname :

DIR="/home/user/mail/work/spam"
LAST="$( basename "$DIR" )"
DIR=""$( dirname "$DIR" )"

приводит к $DIR=/home/user/mail/work и $LAST=spam

Но зачем использовать переменные, когда вы можете просто пройти по самому пути:

while [ "/" \!= $(pwd) ] ; do
    (chmod|setfacl|do_anything) .
    cd .. ;
done
0

Это должно работать:

unset path
parts=$(pwd | awk 'BEGIN{FS="/"}{for (i=1; i < NF; i++) print $i}')

for part in $parts
do
path="$path/$part"
ls -ld $path   # do whatever checking you need here
done
0

В Linux вы можете использовать утилиту namei которая включена в util-linux, чтобы получить список стандартных разрешений Unix:

namei -v path

Ниже приведен еще один сценарий, который не содержит ошибок и должен выполняться в любой современной оболочке, похожей на Bourne. Для разложения пути используется стандартная команда dirname для постепенного удаления последнего компонента до / или . отдыхает (и путь больше не меняется). Просто поместите любой код вместо ls -ld для выполнения на всех компонентах пути (например, getfacl).

#!/bin/sh

f="$1"
p=
while test "$f" != "$p" ; do
    ls -ld "$f"
    p="$f"
    f="$(dirname "$f")"
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .