Проходить по каталогам по заданному пути, пока не будет достигнут существующий каталог

397
Jocky Doe

У меня есть неизвестный путь, указанный пользователем, где я хотел бы создать файл. Поскольку у меня нет разрешений на запись, мне нужно найти первый существующий каталог в пути, идущем изнутри наружу, и проверить наличие разрешений на запись.

Например foo/moo/doo

я пробовал

for d in "$dirpath"/ ; do "dir=$d" done 

Но это не похоже на работу

Поэтому я должен выполнить цикл по пути, является ли он абсолютным или относительным, проверить каждый узел, существует ли он и действительно ли это каталог, и если да, вернуть его

или если не вернуть

  • возможно верхний каталог, если путь абсолютный (не уверен, что всегда есть конкретный каталог в unix поверх абсолютного пути)
  • Текущий каталог с относительным путем

Любые идеи ценят вашу помощь

0
`" 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 

Похожие вопросы