2011-07-10 13 views
36

Jak przekonwertować .. w nazwach ścieżek na bezwzględne nazwy ścieżek w skrypcie bash. To znaczy, jeśli mam ścieżkę /home/nohsib/dvc/../bop, chcę, aby to zostało zmienione na ścieżkę bez kropek, w tym przypadku /home/nohsib/bopJak przekonwertować ".." w nazwach ścieżek na bezwzględną nazwę w skrypcie basha?

Jak mogę to zrobić?

+2

@Tony : Re. twój mod: '' .. ''nie jest elipsą. To tylko dwie kropki ... Jedna kropka oznacza bieżący katalog, a dwie kropki oznaczają rodzica. Elipsa wskazuje nieokreślony zakres. '' .. ''jest bardzo specyficzne. [Ellipsis (operator programujący)] (http://en.wikipedia.org/wiki/Ellipsis_%28programming_operator%29) –

+0

@fred - Dzięki, nie jestem pewien, co tam myślałem. Mogę tylko powiedzieć, że jest późno, za późno na edytowanie pytań SO. Pospiesz się do łóżka. – Tony

+0

To prawdopodobnie należy do witryny wymiany stosu Uniksa ... – jth41

Odpowiedz

40

Co szukasz to readlink:

absolute_path=$(readlink -m /home/nohsib/dvc/../bop) 

Uwaga: Trzeba użyć readlink wersja GNU, która oferuje opcję "-m". Na przykład BSD readlink nie.

+2

Znacznie ładniejszy niż 'cd; rozwiązania pwd'. Warto zauważyć, że odpowiednią funkcją C jest "realpath (3)". –

+1

To nie jest w 100% przenośne, ale powinno działać na większości systemów Linux. – Daenyth

+8

To jest niepoprawna odpowiedź. SO nie musi tłumaczyć dowiązania symbolicznego do rzeczywistej ścieżki, ale rozszerza relatywną ścieżkę do wartości bezwzględnej, czyli różne rzeczy. Przypuśćmy, że mam pliki danych i dowiązanie symboliczne do skryptu w katalogu, jeśli chcesz rozwiązać bezwzględną ścieżkę katalogu, gdy używana jest relatywna ścieżka do dowiązania symbolicznego, więc chcę uzyskać dostęp do plików danych, readlink lub realpath nie powiedzie się –

29

Spróbuj:

ABSOLUTE_PATH=$(cd /home/nohsib/dvc/../bop; pwd) 
+3

Myślę, że ta odpowiedź powinna być na górze. To działa. Jest to platforma wieloplatformowa, w przeciwieństwie do rozwiązań readlink, które mają problemy z OS X. – algal

+0

Działa to tylko dla ścieżek katalogów, a nie ścieżek plików. –

+4

@Craig: 'ABSOLUTE_PATH = $ (cd $ (nazwa_diru {dir lub plik}); pwd)' –

2

Zastosowanie

echo Absolute path: $(cd $1; pwd) 
-1

Spróbuj to (zakładając, że względna ścieżka jest przechowywana w zmiennej $ rel_path):

echo "`cd $rel_path; pwd`" 
+2

Wykonujesz pwd, przechwytujesz jego wyjście, a następnie używasz echo do wydrukowania? Nie, dziękuję, po prostu uruchom pwd bez backticksów i bez echa (które zasadniczo eliminują się nawzajem). –

1

Wystarczy dodatkowa uwaga, jeśli aktualna ścieżka jest pod jego miejsce linku, można rozwiązać prawdziwą drogę z tym:

pwd -P 

celu rozwiązania konkretnego problemu, to wyda polecenie cd aby zmienić katalog na ścieżka bez "..." w niej. Uwaga będzie w tym samym folderze, tylko z poprawną ścieżkę:

cd `pwd -P` 
0

Jako alternatywę dla readlink i realpath GNU, miałem stworzone funkcje, jak dobrze, że będzie działać w skryptach niezależnych poleceń zewnętrznych takich jak pwd i pasz .

http://www.linuxquestions.org/questions/blog/konsolebox-210384/getting-absolute-paths-of-unix-directories-and-filenames-in-shell-scripts-3956/

Jednym z nich jest ten jeden. Spowoduje to zapisanie bezwzględnej ścieżki do $ __. Użyłem tam przeczytać, aby być bezpiecznym przed rozszerzaniem nazw plików.

function getabspath { 
    local -a T1 T2 
    local -i I=0 
    local IFS=/ A 

    case "$1" in 
    /*) 
     read -r -a T1 <<< "$1" 
     ;; 
    *) 
     read -r -a T1 <<< "/$PWD/$1" 
     ;; 
    esac 

    T2=() 

    for A in "${T1[@]}"; do 
     case "$A" in 
     ..) 
      [[ I -ne 0 ]] && unset T2\[--I\] 
      continue 
      ;; 
     .|'') 
      continue 
      ;; 
     esac 

     T2[I++]=$A 
    done 

    case "$1" in 
    */) 
     [[ I -ne 0 ]] && __="/${T2[*]}/" || __=/ 
     ;; 
    *) 
     [[ I -ne 0 ]] && __="/${T2[*]}" || __=/. 
     ;; 
    esac 
} 
0

jeden dobrym rozwiązaniem pod skorupą byłoby:

readlink -ev mypathname 

To wypisuje pełną nazwę ścieżki z kropkami rozwiązane.

7

Jeden problem z użyciem:

ABSOLUTE_PATH=$(cd ${possibleDirectory}; pwd)

jest to, że jeśli $ {possibleDirectory} nie istnieje, absolute_path zostanie ustawiony w bieżącym katalogu. Który prawdopodobnie NIE jest tym, czego potrzebujesz lub czego oczekujesz.

myślę korzystania z tej wersji może być bardziej pożądane ogólnie:

ABSOLUTE_PATH=$(cd ${possibleDirectory} && pwd)

Jeśli $ {possibleDirectory} nie istnieje lub jest niedostępny z powodu brakujących uprawnień dostępu do katalogu, absolute_path będzie zawierał pusty strunowy.

Zaletą tego jest to, że można przetestować pusty ciąg lub pozwolić mu naturalnie, w zależności od okoliczności. Ustawienie domyślne na bieżący katalog w przypadku nieudanego polecenia "cd" może prowadzić do bardzo nieoczekiwanych i prawdopodobnie katastrofalnych wyników (np. Rm -rf "$ ABSOLUTE_PATH")

+0

Działa to tylko dla ścieżek katalogów, a nie ścieżek plików. –

3

Jeśli chcesz to zrobić bez podążania za dowiązaniami symbolicznymi, to spróbuj użyć realpath z opcją -s:

$ realpath -s /home/nohsib/dvc/../bop 
/home/nohsib/bop 

należy zauważyć, że z realpath zwykle wszystko ale ostatni składnik musi istnieć. Tak na powyższe pracować dodaje wszystkie muszą być obecne w systemie plików:

/home 
/home/nohsib 
/home/nohsib/dvc 

Ale można ominąć ten wymóg za pomocą opcji -m.

$ realpath -sm /home/nohsib/dvc/../bop 
/home/nohsib/bop 

(Uwaga realpath nie jest dostępna we wszystkich systemach, zwłaszcza w starszych systemach bez Debiana. Dla tych, którzy pracują na Embedded Linux, niestety Busybox realpath nie obsługuje -s-m lub przełączników).

Powiązane problemy