У меня есть файл /a/b
, который может прочитать пользователь A
. Но /a
не предоставляет права на выполнение A
, и поэтому путь /a/b
не может пройти через /a
. Для произвольно длинного пути, как мне определить причину невозможности доступа к заданному пути из-за того, что промежуточный путь недоступен для пользователя?
Получить причину отказа в разрешении из-за того, что пройденный каталог не является исполняемым
Ответы (4)
Альтернативным ответом на анализ дерева вручную и выявление ошибки в одной строке может быть использование инструмента namei.
namei -mo a/b/c/d
f: a/b/c/d
drwxrw-rw- rasjani rasjani a
drw-rwxr-x rasjani rasjani b
c - No such file or directory
Это показывает всю древовидную структуру и разрешения вплоть до записи, в которой отказано в разрешении.
Что-то вроде этого:
#!/bin/bash
PAR=${1}
PAR=${PAR:="."}
if ! [[ "${PAR:0:1}" == / || "${PAR:0:2}" == ~[/a-z] ]]
then
TMP=`pwd`
PAR=$(dirname ${TMP}/${PAR})
fi
cd $PAR 2> /dev/null
if [ $? -eq 1 ]; then
while [ ! -z "$PAR" ]; do
PREV=$(readlink -f ${PAR})
TMP=$(echo ${PAR}|awk -F\/ '{$NF=""}'1|tr ' ' \/)
PAR=${TMP%/}
cd ${PAR} 2>/dev/null
if [ $? -eq 0 ]; then
if [ -e ${PREV} ]; then
ls -ld ${PREV}
fi
exit
fi
done
fi
Некрасиво, но с работой справится..
Таким образом, идея в основном состоит в том, чтобы взять параметр $ 1, если это не абсолютный каталог, расширить его до такого, а затем удалить последний элемент пути и попытаться перейти в него, если это не удается, промыть и повторить. Если это работает, PREV будет содержать последний каталог, в который пользователь не может перейти, поэтому распечатайте его.
Вот что я собрал. На самом деле я не смотрел на ответ Расджани, прежде чем писать это, но он использует ту же концепцию, когда вы берете статус выхода команды. По сути, он просматривает все каталоги (начиная с самого дальнего по цепочке) и пытается ls
их. Если статус выхода равен 0, то ls
выполнено успешно, и он распечатывает последний каталог, который не смог ls
(я не уверен, что произойдет в некоторых крайних случаях, например, когда вы не можете получить доступ к ничего):
LAST=/a/b
while [ ! -z "$LAST" ] ; do
NEXT=`echo "$LAST" | sed 's/[^\/]*$//' | sed 's/\/$//'`
ls "$NEXT" 2> /dev/null > /dev/null
if [ $? -eq 0 ] ; then
echo "Can't access: $LAST"
break
fi
LAST="$NEXT"
done
и мне нравится помещать такие вещи в одну строку просто для удовольствия:
LAST=/a/b; while [ ! -z "$LAST" ] ; do NEXT=`echo "$LAST" | sed 's/[^\/]*$//' | sed 's/\/$//'`; ls "$NEXT" 2> /dev/null > /dev/null; if [ $? -eq 0 ] ; then echo "Can't access: $LAST"; break; fi; LAST="$NEXT"; done
У меня есть ниже программа C для вас, которая делает это. Ниже приведены шаги
- Скопируйте и сохраните программу как файл .c.
- Скомпилируйте программу с помощью файла gcc.c -o
- Выполните его как ./file PATH
Предполагая, что у вас есть путь как /a/b/c/d и у вас нет разрешения на «c», тогда вывод будет
Given Path = /a/b/c/d
No permission on = /a/b/c
Для разрешения я полагаюсь на ошибку «EACCES». Предполагается, что длина пути равна 1024.
Если у вас есть какие-либо вопросы, пожалуйста, поделитесь.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define MAX_LEN 1024
int main(int argc, char *argv[])
{
char path[MAX_LEN] = "/home/sudhansu/Test";
int i = 0;
char parse[MAX_LEN] = "";
if(argc == 2)
{
strcpy(path, argv[1]);
printf("\n\t\t Given Path = %s\n", path);
}
else
{
printf("\n\t\t Usage : ./file PATH\n\n");
return 0;
}
if(path[strlen(path)-1] != '/')
strcat(path, "/");
path[strlen(path)] = '\0';
while(path[i])
{
if(path[i] == '/')
{
strncpy(parse, path, i+1);
if(chdir(parse) < 0)
{
if(errno == EACCES)
{
printf("\t\t No permission on = [%s]\n", parse);
break;
}
}
}
parse[i] = path[i];
i++;
}
printf("\n");
return 0;
}
С уважением, Судхансу