Проверьте, размещаются ли 2 каталога на том же разделе на Linux

В C,

/* count = 1, wait interval = 1 second, no name lookup, */
/* 10 data bytes, 1 second timeout, 200 millisecond wait time */

sprintf(command,"ping -c1 -i1 -n -s10 -t1 -W200 %u" 
   , connection[port].IPAddress);
err = system(command);
/* err == 0 means OK */
9
10.06.2014, 21:42
4 ответа

Лучшее надежное решение, доступное в POSIX, - это сравнение файлов идентификаторов устройств , предоставленных stat (2) функция .

Perl имеет аналогичную статистическую функцию , как Жиль указал :

perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2

, но «способ POSIX» заключается в использовании программы C, например:

./checksamedev file1 file2

исходный код выглядит следующим образом:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
    struct stat s1, s2;
    if( argc==3 && lstat(argv[1], &s1)==0 && lstat(argv[2], &s2)==0 )
        return !(s1.st_dev == s2.st_dev);
    return 2;
}

Если идентификаторы устройств обоих файлов равны, они размещаются в одной файловой системе, и в этом случае приведенные выше команды возвращают 0 (в противном случае - другое значение). Проверьте с помощью echo $? .

Это хорошо работает с привязкой к монтированию, но, вероятно, не с сетевым монтированием.

0
27.01.2020, 20:05
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1

Работает с любым количеством путей.

4
27.01.2020, 20:05

Следующая команда дает уникальное имя для точки монтирования, содержащей файл $ file :

df -P -- "$file" | awk 'NR==2 {print $1}'

Это работает в любой системе POSIX . Параметр -P устанавливает предсказуемый формат; первое поле второй строки - это «имя файловой системы». Таким образом, чтобы проверить, что два файла находятся под одной и той же точкой монтирования:

if [ "$(df -P -- "$file1" | awk 'NR==2 {print $1}')" = \
     "$(df -P -- "$file2" | awk 'NR==2 {print $1}')" ]; then
  echo "$file1 and $file2 are on the same filesystem" ; fi

Или, чтобы сохранить пару вызовов процессов:

if df -P -- "$file1" "$file2" |
   awk 'NR!=1 {dev[NR] = $1} END {exit(dev[2] != dev[3])}'; then
  echo "$file1 and $file2 are on the same filesystem" ; fi

Некоторые операционные системы могут иметь пробелы в именах томов. В этом случае нет полностью надежного способа синтаксического анализа вывода df .

Под капотом вы можете идентифицировать файловую систему, содержащую файл, по полю st_dev , возвращаемому stat . Нет переносимого способа сделать это из сценария оболочки. В некоторых системах есть утилита stat , но ее синтаксис варьируется:

  • В невстроенных Linux, Cygwin или других системах с GNU coreutils, stat сообщает о st_dev ] при вызове как stat -c% D - "$ file" .
  • Некоторые установки BusyBox включают stat , который совместим с GNU coreutils. У других есть статистика без опции % c ; вы можете использовать stat -t - "$ file" | awk '{print $ 8}' , но это работает, только если имя файла не содержит пробелов, или stat -t - "$ file" | awk 'END {print $ (NF-8)}' , который справляется с произвольными именами файлов, но не с будущим добавлением полей в вывод stat .
  • Системы BSD имеют другую утилиту stat , которая требует stat -f% d - "$ file" .
  • Solaris, AIX и другие не имеют утилиты stat .

Если доступен Perl, вы можете использовать

perl -e 'print ((stat($ARGV[0]))[0])' -- "$file"

и для сравнения:

perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- "$file1" "$file2"

Обратите внимание, что есть некоторые угловые случаи, когда желаемый результат не ясен. Например, при монтировании привязки Linux после mount --bind / foo / bar , / foo и / bar считаются одной и той же файловой системой. Всегда возможно, что два файла на самом деле находятся на одном устройстве, но вы никогда не узнаете: например, если файлы находятся на двух разных сетевых подключениях, клиент не имеет возможности узнать, экспортирует ли сервер разные файловые системы.

Если файлы являются каталогами, и вы можете писать в них, другой способ - создать временный файл и попытаться установить жесткую ссылку. Этот сообщает об отрицательном результате при монтировании привязки Linux.

tmp1=$(TMPDIR=$dir1 mktemp)
tmp2=$(TMPDIR=$dir2 mktemp)
if ln -f -- "$tmp1" "$tmp2"; then
  echo "$dir1 and $dir2 are on the same filesystem, which supports hard links"
fi
rm -f "$tmp1" "$tmp2"
5
27.01.2020, 20:05

Вы можете проверить это с помощью stat:

$ stat -c '%d %m' /proc/sys/
3 /proc

Показывает номер устройства и место, где был смонтирован ваш каталог.

6
27.01.2020, 20:05

Теги

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