|
1 | | -#!/usr/bin/env perl |
| 1 | +#!/usr/bin/env python3 |
2 | 2 | # This script takes a command-line arg of a source directory |
3 | 3 | # that will be passed to rsync, and generates a set of excludes |
4 | 4 | # that will exclude all mount points from the list. This is |
|
27 | 27 | # awk '{print $2}' /proc/mounts | grep -v '^/$' | \ |
28 | 28 | # rsync -avf 'merge,/- -' /dir host:/dest/ |
29 | 29 |
|
30 | | -use strict; |
31 | | -use warnings; |
32 | | -use Cwd 'abs_path'; |
| 30 | +import os, argparse |
33 | 31 |
|
34 | | -my $file = '/proc/mounts'; |
35 | | -my $dir = shift || '/'; |
36 | | -my $trailing_slash = $dir =~ m{./$} ? '/' : ''; |
37 | | -$dir = abs_path($dir) . $trailing_slash; |
38 | | -$dir =~ s{([^/]*)$}{}; |
39 | | -my $trailing = $1; |
40 | | -$trailing = '' if $trailing eq '.' || !-d "$dir$trailing"; |
41 | | -$trailing .= '/' if $trailing ne ''; |
| 32 | +MNT_FILE = '/proc/mounts'; |
42 | 33 |
|
43 | | -open(IN, $file) or die "Unable to open $file: $!\n"; |
44 | | -while (<IN>) { |
45 | | - $_ = (split)[1]; |
46 | | - next unless s{^\Q$dir$trailing\E}{}o && $_ ne ''; |
47 | | - print "- /$trailing$_\n"; |
48 | | -} |
49 | | -close IN; |
| 34 | +def main(): |
| 35 | + trailing_slash = '/' if args.path.endswith(('/', '/.')) and args.path != '/' else '' |
| 36 | + args.path = os.path.realpath(args.path) + trailing_slash |
| 37 | + parent_dir = os.path.dirname(args.path) |
| 38 | + trailing = os.path.basename(args.path) |
| 39 | + if not os.path.isdir(args.path): |
| 40 | + trailing = '' |
| 41 | + elif trailing != '': |
| 42 | + trailing += '/' |
| 43 | + want_path = os.path.join(parent_dir, trailing) |
| 44 | + wp_len = len(want_path) |
| 45 | + |
| 46 | + with open(MNT_FILE) as fh: |
| 47 | + for line in fh: |
| 48 | + mnt_path = line.split()[1] |
| 49 | + if mnt_path.startswith(want_path) and mnt_path != want_path: |
| 50 | + print(f"- /{trailing}{mnt_path[wp_len:]}") |
| 51 | + |
| 52 | +if __name__ == '__main__': |
| 53 | + parser = argparse.ArgumentParser(description="Output mount points as rsync excludes.", add_help=False) |
| 54 | + parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.") |
| 55 | + parser.add_argument('path', metavar='PATH', nargs='?', default='/', help="Limit output to those within the PATH hierarchy.") |
| 56 | + args = parser.parse_args() |
| 57 | + main() |
| 58 | + |
| 59 | +# vim: sw=4 et |
0 commit comments