/my/dir
と同じパーティションにあることを確認する方法は/
?
これはスクリプトに統合するためのものです。バインドマウントは正しく処理する必要があります。 POSIX準拠のソリューションを歓迎します。
答え1
statを使用して次のことを確認できます。
$ stat -c '%d %m' /proc/sys/
3 /proc
デバイス番号とディレクトリがインストールされている場所を表示します。
答え2
次のコマンドは、ファイルを含むマウントポイントに一意の名前を付けます$file
。
df -P -- "$file" | awk 'NR==2 {print $1}'
これはすべての場合に適用されます。POSIXシステム。この-P
オプションは予測可能な形式を適用します。 2行目の最初のフィールドは「ファイルシステム名」です。したがって、両方のファイルが同じマウントポイントにあることを確認するには、次の手順を実行します。
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と互換性があります。他の人は選択の余地がstat
ありません%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
は同じファイルシステムと見なされます。両方のファイルが実際には同じデバイスにある可能性がありますが、わかりません。たとえば、ファイルが2つの異なるネットワークマウントにある場合、クライアントはサーバーが異なるファイルシステムをエクスポートしているかどうかを知ることはできません。/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"
答え3
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1
複数のパスで動作します。
答え4
POSIXで利用可能な最も明確な解決策は、ファイルを比較することです。デバイスID提供: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;
}
両方のファイルのデバイスIDが同じ場合は同じファイルシステムでホストされます。この場合、上記のコマンドは0を返します(そうでない場合は別の値を返します)。で確認してくださいecho $?
。
これはバンドルインストールでは機能しますが、ネットワークインストールでは機能しない可能性があります。