команда bash / fish для друку абсолютного шляху до файлу


448

Запитання: чи існує проста команда sh / bash / zsh / fish / ... для друку абсолютного шляху до того файлу, яким я його подаю?

Випадок використання: Я перебуваю в директорії , /a/bі я хотів би, щоб надрукувати повний шлях до файлу cв командному рядку , так що я можу легко вставити його в іншу програму: /a/b/c. Проста, але невелика програма для цього може, ймовірно, врятувати мене 5 секунд, якщо справа стосується обробки довгих шляхів, що, врешті-решт, додає. Тож мене дивує, що я не можу знайти стандартну утиліту для цього - чи насправді такої немає?

Ось приклад реалізації, abspath.py:

#!/usr/bin/python
# Author: Diggory Hardy <diggory.hardy@gmail.com>
# Licence: public domain
# Purpose: print the absolute path of all input paths

import sys
import os.path
if len(sys.argv)>1:
    for i in range(1,len(sys.argv)):
        print os.path.abspath( sys.argv[i] )
    sys.exit(0)
else:
    print >> sys.stderr, "Usage: ",sys.argv[0]," PATH."
    sys.exit(1)

Я заперечую, що відповідь @ DennisWilliamson (за допомогою параметра -m) є кращою за те, що вона (як правило) є більш портативною та працює з файлами, які не існують.
TTT

Або відповідь Флімма; обидва - це хороші рішення. Однак Баньє найкраще відповідає на моє оригінальне запитання.
безтурботний

3
Користувачі OSX: дивіться цю відповідь
Ян

Відповіді:


562

Спробуйте realpath.

$ realpath example.txt
/home/username/example.txt

133
+1, дуже приємна програма. Але зауважте, що це зовнішня команда (а не вбудована оболонка) і може не бути присутнім у кожній системі за замовчуванням, тобто вам може знадобитися її встановити. У Debian він знаходиться в окремому пакеті з тим же ім'ям.
Роман Чепляка

5
Я додав у свій шлях складання realpath: github.com/westonruter/misc-cli-tools/blob/master/realpath
Вестон Рутер

1
@Flimm: Це все одно надасть тобі дійсний шлях із заданим відносним шляхом. Якщо ви хочете дізнатися про існування файлів, використовуйте інший інструмент, наприклад, тест.
Бенджамін Баньє

14
@Dalin: Спробуйте встановити coreutils. Двійковий називається grealpath.
Тоні Пеня-Альба

5
Цей інструмент був представлений у GNU coreutils 8.15 (у 2012 році), тому він є досить новим.
квітня

319

Спробуйте readlinkвирішити символьні посилання:

readlink -e /foo/bar/baz

50
Я вважаю за краще використовувати "-f" замість "-e", щоб ми могли бачити абсолютний шлях неіснуючого файлу.
hluk

5
Мені це здається найпростішим, в той же час є портативним. readlink є портом gnu coreutils, тому він буде встановлений майже на будь-якому дистрибутиві Linux, крім деяких вбудованих.
котфій

14
Мені здається, -mце найкращий варіант використання.
Метт Столяр

1
@Dalin: /usr/bin/readlinkна Mavericks. Або ви мали на увазі, що ці параметри не знайдені в OS X? Здається, це відшарована версія BSD ...: p
iconoclast

14
@iconoclast Ці параметри недоступні для OSX, а відповідно до сторінки BSD readlink: only the target of the symbolic link is printed. If the given argument is not a symbolic link, readlink will print nothing and exit with an errorтому readlink не працюватиме з цією метою для OSX
SnoringFrog

257
#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"

8
Не забудьте процитувати всі речі. Якщо ви не розумієте, чому, спробуйте свою програму у файлі a b(два пробіли між a і b, SO з'їдає один з них).
Роман Чепляка

1
також спробуйте це на "/" це перетворюється на "///"
Джордж

35
єдине на сьогодні рішення POSIX, яке не вимагає від вас писати та компілювати виконуваний файл, оскільки readlink та realpath не є POSIX
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

25
Раніше я function realpath { echo $(cd $(dirname $1); pwd)/$(basename $1); }робив собі realpathкоманду (зараз прийняту відповідь) в ОС X. Дякую!
Джеймс Бедфорд

1
Я використовував цей метод для визначення імен файлів журналу для сценаріїв:LOG=$(echo $(cd $(dirname $0); pwd)/$(basename $0 .sh).log)
DrStrangepork

85

Забудьте про readlinkі realpathякі можуть або не можуть бути встановлені на вашій системі.

Розширюючись на відповідь догбена вище, тут вона виражається як функція:

#!/bin/bash
get_abs_filename() {
  # $1 : relative filename
  echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}

Ви можете використовувати його так:

myabsfile=$(get_abs_filename "../../foo/bar/file.txt")

Як і чому це працює?

Рішення використовує той факт, що вбудована pwdкоманда Bash надрукує абсолютний шлях поточного каталогу при виклику без аргументів.

Чому мені подобається це рішення?

Це портативний і не вимагає ні readlinkабо realpathщо часто не існує по дефолту не встановити даний Linux / Unix дистрибутив.

Що робити, якщо режисера не існує?

Як зазначено вище, функція вийде з ладу і надрукується на stderr, якщо вказаний шлях до каталогу не існує. Це може бути не те, що ви хочете. Ви можете розширити функцію для вирішення цієї ситуації:

#!/bin/bash
get_abs_filename() {
  # $1 : relative filename
  if [ -d "$(dirname "$1")" ]; then
    echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
  fi
}

Тепер він поверне порожній рядок, якщо одного з батьківських dirs не існує.

Як ви обробляєте трейлінг ".." або "." у вхід?

Що ж, це дає абсолютний шлях у такому випадку, але не мінімальний. Це буде виглядати так:

/Users/bob/Documents/..

Якщо ви хочете вирішити "..", вам слід зробити сценарій таким чином:

get_abs_filename() {
  # $1 : relative filename
  filename=$1
  parentdir=$(dirname "${filename}")

  if [ -d "${filename}" ]; then
      echo "$(cd "${filename}" && pwd)"
  elif [ -d "${parentdir}" ]; then
    echo "$(cd "${parentdir}" && pwd)/$(basename "${filename}")"
  fi
}

Хороша функція, але, мабуть, ви не зрозуміли питання. Я хотів щось для інтерактивного використання, а не сценарії.
похмурий

3
Я хотів би додати, що realpathпостачається з пакету coreutils, який також містить такі інструменти, як who, touchабо cat. Це досить стандартний набір інструментів GNU, тож ви можете бути впевнені, що це встановлено майже на будь-якій машині на базі Linux.Таким чином, ви маєте рацію: з ним є дві проблеми: i) ви, швидше за все, пропустите його в установці за замовчуванням на не для GNU unix-систем (як OpenBSD) ii) цей інструмент був представлений у версії 8.15 (тому він зовсім новий, з 2012 року), тому ви будете сумувати за довготривалими стабільними системами (як RHEL 6).
квітня

1
Ну, мабуть, здається, що Continuum Analytics (виробникам дистрибуції Anaconda Python ) сподобалась ця відповідь. Він реалізований (з посиланням на це посилання тут) у їхньому "активуванні" сценарії , який використовується для активації віртуальних середовищ, створених інструментом conda. Отже… хороший!
wjv

1
Це працює лише для каталогів (оскільки іншого немає) і не може впоратися з ".." і ".". Дивіться мою відповідь , який повинен обробляти всі: stackoverflow.com/a/23002317/2709
Олександр Klimetschek

3
@marbu realpath не присутній на Ubuntu 14.04 або на Debian Wheezy. З часом це може стати дещо стандартним, але зараз, звичайно, це не так. Також зауважте, що ОП нічого не сказала про Linux чи GNU. Bash більш широко використовується, ніж це.
mc0e

77
$ readlink -m FILE
/path/to/FILE

Це краще, ніж readlink -e FILEабо realpath, тому що він працює, навіть якщо файл не існує.


Приємно. Це також працює на файли / каталоги, які існують, але не є посиланнями.
тихість

У мене є посилання для читання, доступні на OS X 10.9 (Mavericks), тому це, безумовно, найкраща відповідь тут.
Кеннет Хосте

6
@KennethHoste: -mопція недоступна для Mavericks.
іконоборство

2
Однозначно це не на установці DEFAULT OSX.
Fran Marzoa

працює на linux (CentOS) дякую, тому що для нього не існувало
realpath

66

Це відносний шлях до функції оболонки перетворювача абсолютного шляху

  • не потребує утиліт (просто cdі pwd)
  • працює для каталогів та файлів
  • ручки ..і.
  • обробляє пробіли в режимі dir або файли
  • вимагає, щоб файл чи каталог існували
  • нічого не повертає, якщо на даному шляху нічого не існує
  • обробляє абсолютні шляхи як вхідні (проходить їх по суті)

Код:

function abspath() {
    # generate absolute path from relative path
    # $1     : relative filename
    # return : absolute path
    if [ -d "$1" ]; then
        # dir
        (cd "$1"; pwd)
    elif [ -f "$1" ]; then
        # file
        if [[ $1 = /* ]]; then
            echo "$1"
        elif [[ $1 == */* ]]; then
            echo "$(cd "${1%/*}"; pwd)/${1##*/}"
        else
            echo "$(pwd)/$1"
        fi
    fi
}

Зразок:

# assume inside /parent/cur
abspath file.txt        => /parent/cur/file.txt
abspath .               => /parent/cur
abspath ..              => /parent
abspath ../dir/file.txt => /parent/dir/file.txt
abspath ../dir/../dir   => /parent/dir          # anything cd can handle
abspath doesnotexist    =>                      # empty result if file/dir does not exist
abspath /file.txt       => /file.txt            # handle absolute path input

Примітка. Це засновано на відповідях від nolan6000 та bsingh , але виправляє файл файлу.

Я також розумію, що оригінальне питання стосувалося наявної утиліти командного рядка. Але оскільки це, здається, є питанням щодо stackoverflow для цього, включаючи сценарії оболонки, які хочуть мати мінімальні залежності, я ставлю це рішення скрипту, тому я можу знайти його пізніше :)


Дякую. Ось що я йду на OSX
Грег

Це не працює для каталогів з пробілами, тобто: $ abspath 'a b c/file.txt'Це тому, що аргумент cdне цитується. Щоб подолати це, замість того, щоб цитувати весь аргумент на echo(чи є причина у цих цитатах?), Цитуйте лише аргументи шляху. Тобто замінити echo "$(cd ${1%/*}; pwd)/${1##*/}"на echo $(cd "${1%/*}"; pwd)/${1##*/}.
Джордж

@george Дякую, що зауважив, я це виправив.
Олександр Климечек

1
Я переглянув десятки напіврозкладених рішень, і це, безумовно, виявляється найбільш стислим і точним рішенням, яке стосується лише удару. Ви можете зменшити його ще більше, замінивши echo "$(cd "$1"; pwd)"на (cd "$1"; pwd). Тут немає необхідності в луні.
Шість

@Six True, оновлено. Підтяжки ( ... )все ще потрібні, тому це cdвідбувається в підрозділі , оскільки ми не хочемо змінювати робочий каталог для будь-яких абонентів abspath.
Олександр Климечек

24

findКоманда може допомогти

find $PWD -name ex*
find $PWD -name example.log

Список усіх файлів у поточному каталозі або під ним з іменами, що відповідають шаблону. Ви можете спростити його, якщо ви отримаєте лише кілька результатів (наприклад, каталог біля нижньої частини дерева, що містить кілька файлів)

find $PWD

Я використовую це на Solaris 10, у якому немає інших згаданих утиліт.


1
я не копчив цей коментар у першому читанні; Ключовим моментом тут є те, що якщо ви дасте абсолютний шлях команді find, то вона виведе результати в абсолютному шляху. тому використання $ PWD - це абсолютний шлях, де ви знаходитесь, щоб ви отримали результат як абсолютний.
simbo1905

4
Якщо ви покладаєтесь PWD, ви можете просто використовувати $PWD/$filename.
jonny

Цей підхід можна вдосконалити за допомогою -maxdepth 1. Також не забувайте про цитування - потенційні проблеми із безпекою тут, залежно від того, як ви цим користуєтеся.
mc0e

1
@jonny: $ PWD / $ ім'я файлу не вдається, якщо $ filename вже абсолютний.
mc0e

Це не вдається, якщо ім'я файлу вказано як "./filename.txt" (з провідною крапкою та косою рисою).
Марк Стосберг

15

Якщо у вас немає утиліт readlink або realpath, ви можете скористатися наступною функцією, яка працює в bash і zsh (не впевнені в решті).

abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; }

Це також працює для неіснуючих файлів (як і функція python os.path.abspath).

На жаль abspath ./../somefile, не позбудеться крапок.


1
Виглядає портативно для мене. З іншого боку, зламається, наприклад, на ім'я файлу, що містить новий рядок.
Роман Чепляка

1
Для подальшого покращення замініть echo "$1"на printf "%s\n" "$1"(те ж саме з другим відлунням). echoможе інтерпретувати зворотні риски всередині своїх аргументів
Роман Чепляка

Знову ж, ти маєш рацію! Дійсно, поведінка команди echo в zsh відрізняється від bash.
hluk

1
Строго кажучи, за POSIX поведінка ехо не визначено, якщо аргументи містять зворотні риски. Однак він визначається під розширенням XSI (а саме ехо має інтерпретувати послідовності втечі). Але і bash, і zsh далекі навіть від відповідності POSIX ...
Роман Чепляка,

Вибачте, але я не бачу сенсу. Я вже надав відповідь як скрипт з додатковими функціями, що це, і це не потрібно використовувати в сценарії оболонки.
dhardy

10

Ось лише функція zsh, яка мені подобається за її компактність. Він використовує модифікатор розширення 'A' - див. Zshexpn (1).

realpath() { for f in "$@"; do echo ${f}(:A); done }

Вау, це елегантне рішення !!
ShellFish

6

Існує правило , немає такого поняття , як в файл (це твердження означає , що там може бути більше , ніж один в цілому, тому використання означеного артикля не підходить). A - це будь-який шлях, що починається від кореня "/" і позначає файл без неоднозначності незалежно від робочого каталогу. (Див., Наприклад, wikipedia ). absolute pathabsolute path

A relative path- шлях, який слід інтерпретувати, починаючи з іншого каталогу. Це може бути робочий каталог, якщо це relative pathманіпулювання програмою (хоча і не обов'язково). Якщо він знаходиться у символічному посиланні в каталозі, він, як правило, має відношення до цього каталогу (хоча користувач може мати на увазі й інше використання).

Отже, абсолютний шлях - це лише шлях відносно кореневого каталогу.

Шлях (абсолютний або відносний) може містити або не містити символічні посилання. Якщо цього немає, це також дещо не сприймає зміни в сполучній структурі, але це не обов'язково і навіть не бажано. Деякі люди називають canonical path(або canonical file nameабо resolved path) тим, absolute pathу якому всі символічні посилання були вирішені, тобто були замінені шляхом до туди, до якої вони посилаються. Команди realpathі readlinkобидва шукають канонічний шлях, але realpathє лише можливість отримати абсолютний шлях, не намагаючись вирішити символічні посилання (поряд з кількома іншими варіантами для отримання різного роду шляхів, абсолютних чи відносних до деякого каталогу).

Це вимагає декількох зауважень:

  1. символічні посилання можуть бути вирішені лише в тому випадку, якщо все, до чого вони мають посилатися, вже створене, що, очевидно, не завжди так. Команди realpathта readlinkопції для обліку цього.
  2. каталог на шляху згодом може стати символічним посиланням, що означає, що шлях більше не є canonical. Отже, концепція залежить від часу (або навколишнього середовища).
  3. навіть в ідеальному випадку, коли всі символічні посилання можуть бути вирішені, canonical pathдо файлу все ще може бути більше одного з двох причин:
    • розділ, що містить файл, можливо, був встановлений одночасно ( ro) у кількох точках кріплення.
    • можуть бути жорсткі посилання на файл, тобто по суті файл існує в декількох різних каталогах.

Отже, навіть при набагато більш обмеженому визначенні canonical pathдо файлу може бути кілька канонічних шляхів до файлу. Це також означає, що класифікатор canonicalдещо неадекватний, оскільки зазвичай передбачає поняття унікальності.

Це розширює коротке обговорення теми у відповіді на інше подібне запитання у Bash: пошук абсолютного шляху, заданого відносним

Мій висновок полягає в тому, що realpathвін краще розроблений і набагато гнучкіший, ніж readlink. Єдине використання, readlinkяке не охоплено, realpath- це дзвінок без опції, що повертає значення символічного посилання.


Я не проти того, щоб бути прихильним, але мені подобається розуміти, чому так, щоб я міг щось дізнатися, або технічне, або щодо того, що вважається належною практикою на сайті. Ну ... принаймні це спонукало мене зареєструватися в Meta Stack Overflow, щоб краще зрозуміти місцеву соціологію. Я рекомендую це. - Все-таки, якщо хтось має думку про недоцільність моєї відповіді, мене цікавить.
бабу

1
(а) запитання має дійсну відповідь 2 + 1/2 роки тому, (b) існує (єдиний) абсолютний шлях, відповідний відносному шляху (який я хотів), хоча, можливо, не до файлу, як ви вказано наголошено. До речі, будь-які коментарі щодо realpathvs readlinkабо навіть щодо символічних посилань є надлишком до того, про що я запитав.
dhardy

1
Другий коментар: короткі відповіді дуже часто корисніші, ніж довгі лекції. Переповнення стека зазвичай використовується для задавання конкретних питань.
безтурботний

5
1 - той факт, що питання настільки довгий час має правильну відповідь, не означає, що воно закрите. Питання не призначені лише для особистого користування. Дійсно, є відповіді, які збирають більше голосів, ніж підтверджена відповідь. А з новими інструментами "найкраща" відповідь може змінюватися з часом. Багато людей використовують старі відповіді, доступ до яких здійснюється за допомогою веб-пошуку.
бабу

1
2 - Ви наполягаєте на тому, що існує (єдиний) абсолютний шлях, відповідний відносному шляху . Хоча я здогадуюсь, що ви маєте на увазі під "відповідним", тобто шляхом, отриманим від оригіналу через заданий набір перетворень, ваше твердження досі неправильне. Існує унікальний "відповідний" канонічний шлях. Саме слово canonicalпосилається саме на цю унікальність щодо сукупності перетворень. Але, наприклад, / dev / cdrom - це абсолютно хороший абсолютний шлях, навіть якщо він насправді є посиланням на / dev / sr0. Обидва вказують на один і той же пристрій. Моя оригінальна відповідь вказувала на відповідну веб-статтю.
бабу

5

dogbane Відповідь з описом того, що гряде на:

#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"

Пояснення:

  1. Цей сценарій отримує відносний шлях як аргумент "$1"
  2. Тоді ми отримуємо частину dirname цього шляху (ви можете передати або dir або файл до цього сценарію):dirname "$1"
  3. Потім ми cd "$(dirname "$1")переходимо до цього відносного режиму і отримуємо абсолютний шлях до нього, запустивши pwdкоманду shell
  4. Після цього додаємо базове ім'я до абсолютного шляху:$(basename "$1")
  5. Як завершальний крок ми echoце зробимо

2

Для каталогів dirnameспрацьовує ../і повертається ./.

Функцію nolan6000 можна змінити, щоб виправити таке:

get_abs_filename() {
  # $1 : relative filename
  if [ -d "${1%/*}" ]; then
    echo "$(cd ${1%/*}; pwd)/${1##*/}"
  fi
}

1
Ласкаво просимо до SO! Для невеликих змін та зауважень додавання коментаря до існуючої відповіді може бути більш доцільним, ніж додавання відповіді, особливо якщо в цій скопійованій відповіді бракує багато іншої інформації вихідної відповіді. Коли ви зібрали трохи більше репутації, ви зможете додати коментарі до відповідей інших людей. Наразі спробуйте зібрати репутацію, задаючи унікальні, цінні питання або надаючи окремі, хороші відповіді.
cfi

1
Оскільки ви посилаєтесь на відповідь nolan6000, зауважте, що плакат Дхарді вже прокоментував, що не прийме відповіді nolan6000, оскільки не шукає сценарій. Тож строго кажучи ваша відповідь не відповідає на запитання.
cfi

функція може бути додана .profileі, отже, доступна для інтерактивного використання.
адиб

Це не працює, якщо $1звичайне ім'я файлу: get_abs_filename foo-> нічого (або <current_dir>/foo/fooякщо fooце каталог).
ivan_pozdeev

2

Це не відповідь на питання, але для тих, хто робить сценарії:

echo `cd "$1" 2>/dev/null&&pwd||(cd "$(dirname "$1")";pwd|sed "s|/*\$|/${1##*/}|")`

він правильно обробляє / .. ./ тощо. Я також, здається, працює над OSX


2

Я розмістив наступний скрипт у своїй системі, і я називаю це псевдонімом bash, коли я хочу швидко схопити повний шлях до файлу в поточному режимі:

#!/bin/bash
/usr/bin/find "$PWD" -maxdepth 1 -mindepth 1 -name "$1"

Я не впевнений, чому, але в OS X при виклику сценарієм "$ PWD" розширюється до абсолютного шляху. Коли в командному рядку викликається команда find, вона не відбувається. Але це робить те, що я хочу ... насолоджуватися.


$PWDзавжди має абсолютний шлях робочого каталогу. Крім того, findне потерпить косої риси, тому ви не відповідаєте на запитання, як задали. Швидший спосіб зробити те, що ви хочете зробити, буде простоecho "$PWD/$1"
Адам Кац

2

Можливо, найпростішим, якщо ви хочете використовувати лише вбудовані:

find `pwd` -name fileName

Введіть лише два слова, і це буде працювати на всіх системах Unix, а також на OSX.


Я б додав -maxdepth 1раніше -name(припустимо, що файл знаходиться в поточному каталозі). Без цього він буде працювати з файлами в будь-якому підкаталозі pwd, але не з іншими.
Вальтер Трос

Дійсно, ви праві, питання вказувало, що файл буде у поточному каталозі. Що ви маєте на увазі "але не з іншими"?
Арж

Я маю на увазі find, що не знайдете файл поза деревом каталогів під ним pwd. Наприклад, якщо ви намагаєтеся find . -name ../existingFile, це не вдається.
Вальтер Трос

Досить справедливо, так, це передбачає, що ви хочете надрукувати повний шлях до файлу у вашому реєстрі (за оригінальним запитанням) або в будь-якому місці дерева ваших cwd (не в оригінальному запитанні).
Арж

1
#! /bin/bash

file="$@"
realpath "$file" 2>/dev/null || eval realpath $(echo $file | sed 's/ /\\ /g')

Це компенсує недоліки realpath, зберігайте їх у сценарії оболонки fullpath. Тепер ви можете телефонувати:

$ cd && touch a\ a && rm A 2>/dev/null 
$ fullpath "a a"
/home/user/a a
$ fullpath ~/a\ a
/home/user/a a
$ fullpath A
A: No such file or directory.

Що це вирішує? realpath "foo bar"-> /home/myname/foo bar. Якщо вам не завадить цитувати аргументи командного рядка, це не realpathвинна.
ivan_pozdeev

Домовились, це більше зручність обгортки.
ShellFish

1

Альтернатива отримати абсолютний шлях у Ruby :

realpath() {ruby -e "require 'Pathname'; puts Pathname.new('$1').realpath.to_s";}

Працює без аргументів (поточна папка) та відносного та абсолютного шляху до файлу чи папки як agument.


0

Відповідь з домашньою мовою

realpathнайкраща відповідь, але якщо у вас її не встановлено, спершу слід запустити, brew install coreutilsякий встановить coreutils з великою кількістю дивовижних функцій. Написати власну функцію та експортувати її занадто багато роботи та ризику помилки для чогось подібного, ось два рядки:

$ brew install coreutils
$ realpath your-file-name.json 

-1

Ей, хлопці, я знаю, що це стара тема, але я просто розміщую це для посилання на всіх інших, хто відвідував це, як я. Якщо я правильно зрозумів питання, думаю, що locate $filenameкоманда. Він відображає абсолютний шлях наданого файлу, але лише за наявності.


4
locateце утиліта для пошуку файлів / шляхів по імені. Це може зробити цю роботу, але може також знайти інші збіги та може не знайти існуючий файл без виклику updatedbспочатку root.
похмурий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.