В 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 */
Лучшее надежное решение, доступное в 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 $?
.
Это хорошо работает с привязкой к монтированию, но, вероятно, не с сетевым монтированием.
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1
Работает с любым количеством путей.
Следующая команда дает уникальное имя для точки монтирования, содержащей файл $ 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
, но ее синтаксис варьируется:
stat
сообщает о st_dev
] при вызове как stat -c% D - "$ file"
. stat
, который совместим с GNU coreutils. У других есть статистика
без опции % c
; вы можете использовать stat -t - "$ file" | awk '{print $ 8}'
, но это работает, только если имя файла не содержит пробелов, или stat -t - "$ file" | awk 'END {print $ (NF-8)}'
, который справляется с произвольными именами файлов, но не с будущим добавлением полей в вывод stat
. stat
, которая требует stat -f% d - "$ file"
. 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"
Вы можете проверить это с помощью stat:
$ stat -c '%d %m' /proc/sys/
3 /proc
Показывает номер устройства и место, где был смонтирован ваш каталог.