2016-04-02 38 views
2

我有一個文件/a/b,用戶可以讀A。但/a不提供A的可執行權限,因此路徑/a/b不能遍歷/a。對於任意長的路徑,我如何確定由於用戶不能訪問中間路徑而無法訪問給定路徑的原因?獲取由於遍歷的目錄無法執行而導致權限被拒絕的原因

+0

你會發現我的答案的http://計算器。com/questions/29570203/unix-installer -cant-find-path-to-file-even-im-enter-the-exact-path/29571473#29571473幫助(但不是直接解決方案)。祝你好運。 – shellter

回答

2

手動解析樹和查明e的替代答案對單行的rror將使用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 

這顯示了整個樹結構和權限,直到權限被拒絕的條目。

+0

這是我不知道的東西,似乎是最合乎邏輯的預先存在的解決方案。 –

1

東西沿着這樣的:

#!/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 

醜陋,但它會完成這項工作..

這樣的想法是basicly,服用參數$ 1,如果它不是絕對目錄,擴大到然後刪除路徑的最後一個元素,並嘗試將其放入CD中,如果它失敗,則rince和repeat。如果它起作用,PREV將保存用戶無法放入的最後一個目錄,因此將其打印出來。

+0

你能否提供一個參考資料,指出沒有更好的選擇,或者這是做這件事的傳統方式? –

+0

沒有關於優越的選擇的想法,因爲這也是相當不好的,它的字符串解析可能會失敗。另一種選擇是使用find -type -d $ PAR進行從下到上的迭代,grep爲「Permission denied」的stderr,grep對PAR的錯誤以避免其他子目錄顯示..會更漂亮。 – rasjani

+0

所以,迭代是關鍵,因爲沒有其他方式可以報告AFAIK是否在通向實際端點的路徑內阻止訪問。可能使用test -x || test -r檢查,但也可能失敗,因爲它沒有提供路徑中哪個點的訪問被拒絕的信息。 – rasjani

1

這就是我扔在一起。在寫這篇文章之前,我其實並沒有看到rasjani的回答,但是它在使用命令的退出狀態時使用了相同的概念。基本上它經歷了所有的目錄(從鏈條的最遠處開始)並嘗試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 
1

我有下面的C程序爲你哪些做到這一點。以下是步驟

  1. 將程序複製並保存爲file.c.
  2. 用gcc編譯file.c程序-o文件將
  3. 執行它./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; 
    } 

問候, Sudhansu

相關問題