Проходить по каталогам по заданному пути, пока не будет достигнут существующий каталог
397
Jocky Doe
У меня есть неизвестный путь, указанный пользователем, где я хотел бы создать файл. Поскольку у меня нет разрешений на запись, мне нужно найти первый существующий каталог в пути, идущем изнутри наружу, и проверить наличие разрешений на запись.
Например foo/moo/doo
я пробовал
for d in "$dirpath"/ ; do "dir=$d" done
Но это не похоже на работу
Поэтому я должен выполнить цикл по пути, является ли он абсолютным или относительным, проверить каждый узел, существует ли он и действительно ли это каталог, и если да, вернуть его
или если не вернуть
возможно верхний каталог, если путь абсолютный (не уверен, что всегда есть конкретный каталог в unix поверх абсолютного пути)
Текущий каталог с относительным путем
Любые идеи ценят вашу помощь
`" dir = $ d "` не делает то, что вы ожидаете. вам нужно указать только значение, а не все назначение.
l0b0 6 лет назад
0
@ l0b0 как мне получить только значение?
Jocky Doe 6 лет назад
0
Я не знаю, что ты имеешь в виду. Не могли бы вы обновить свой вопрос, включив в него [пример] (https://stackoverflow.com/help/mcve)?
l0b0 6 лет назад
1
Пожалуйста, уточните: хотите ли вы найти (1) каталог типа `. / Unknown / частичный / путь / foo / moo / doo`? или (2) самый длинный существующий путь из набора `. / foo / moo / doo`,`. / foo / moo`, `. / foo`,` .`? или (3) что-то еще?
Kamil Maciorowski 6 лет назад
0
@KamilMaciorowski Мне нужно зациклить путь изнутри наружу, что означает начать с `doo`, и когда я достигну существующего dir в пути, я должен остановиться и затем проверить наличие разрешений на запись. Я не могу проверить несуществующую папку для разрешения записи. Путь может быть любым, потому что пользователь сценария дает его.
Jocky Doe 6 лет назад
0
Так как (2), верно?
Kamil Maciorowski 6 лет назад
0
@KamilMaciorowski Да, нравится (2)
Jocky Doe 6 лет назад
0
делает `if [[-d" $ dirpath "]]; затем echo "$ dirpath - это каталог"; делать то, что тебе нужно? Я все еще нахожу описание вашей проблемы очень неясным.
glenn jackman 6 лет назад
0
@glennjackman Каталог может не существовать, поэтому мне нужно зацикливаться, пока я не найду существующий в пути, а затем проверить разрешение на запись, чтобы создать остальные несуществующие
Jocky Doe 6 лет назад
0
«чтобы создать остальные несуществующие» - см. «mkdir -p».
Kamil Maciorowski 6 лет назад
1
@KamilMaciorowski Но как проверить, есть ли у меня разрешения на запись для пути? Я запускаю сторонние скрипты в каталоге, поэтому нет супер пользователя.
Jocky Doe 6 лет назад
0
Если у вас нет прав на запись, вы все равно не можете «создать остальные несуществующие», не так ли? Может быть, если каталог без записи пуст и вы не можете удалить его; или это ваш каталог, и вы можете дать себе разрешения. На твоем месте я бы [KISS] (https://en.wikipedia.org/wiki/KISS_principle). Если mkdir -p возвращает «отказано в разрешении», предположим, что есть причина, по которой разрешения - это то, что они есть, и лучшее, что может сделать ваш скрипт, - выдать ошибку; тогда вы расследуете вручную. Любая громоздкая логика сценария может иметь неприятные последствия.
Kamil Maciorowski 6 лет назад
1
2 ответа на вопрос
1
Ljm Dullaart
Просто быстрое решение
#!/bin/bash dir=$(realpath "$1") stop=no while [ $stop = no ] ; do if touch "$dir/this.$$" ; then rm "$dir/this.$$" echo "You can create in $dir!" stop=yes else dir=$ if [ "$dir" = "" ] ; then echo "You are not allowed to write anywhere." stop=yes fi fi done
10 раз ваш ответ помог мне сделать функцию, которая делает работу
Jocky Doe 6 лет назад
0
Если это решило вашу проблему, отметьте решение как таковое.
Ljm Dullaart 6 лет назад
0
0
Jocky Doe
Вот функция, которая находит первый существующий каталог в пути, начиная с самого глубокого местоположения в пути.
function findConcreteDirInPath() { local dirpath="$1" local stop="no" while [ $stop = "no" ] ; do if [ -d "$dirpath" ]; then local stop="yes" else local dirpath=$(dirname "$dirpath") if [ "$dirpath" = "" ] ; then local stop="yes" exit 1; fi fi done echo "$dirpath" }
Вот пример использования
aPath="/var/doo/moo" concreteDir=$(findConcreteDirInPath $aPath) if [ $concreteDir != "." ]; then echo -e "First concrete dir in \"$aPath\" path is: \"$concreteDir\"" # Check whether current user have write permissions for the directory if [ -w $concreteDir ]; then echo -e "\"$(whoami)\" user can write in \"$concreteDir\"" else echo -e "\"$(whoami)\" user can NOT write in \"$concreteDir\"" fi else echo -e "No concrete dir for the given \"$aPath\" path" fi