#!/usr/bin/env python3 import argparse import glob import os import sys def main(): parser = argparse.ArgumentParser(description="remote glob helper for UniDesk ssh passthrough") parser.add_argument("patterns", nargs="*", help="glob patterns relative to --root unless absolute") parser.add_argument("--root", default=".", help="base directory for relative patterns") parser.add_argument("--pattern", action="append", default=[], help="additional glob pattern") parser.add_argument("--contains", action="append", default=[], help="match path names containing text") parser.add_argument("--icontains", action="append", default=[], help="case-insensitive contains match") parser.add_argument("--type", choices=["any", "f", "d"], default="any", help="filter by any/file/dir") parser.add_argument("--limit", type=int, default=0, help="maximum number of rows to print") parser.add_argument("--sort", action="store_true", help="sort output") parser.add_argument("--absolute", action="store_true", help="print absolute paths") args = parser.parse_args() if args.limit < 0: print("glob: --limit must be >= 0", file=sys.stderr) return 2 root = os.path.abspath(args.root) patterns = list(args.patterns) + list(args.pattern) for text in args.contains: patterns.append(f"**/*{text}*") for text in args.icontains: # Python glob is case-sensitive on Linux, so filter from a broad recursive scan. patterns.append("**/*") if not patterns: patterns = ["*"] seen = set() rows = [] lowered_contains = [text.lower() for text in args.icontains] for pattern in patterns: effective = pattern if os.path.isabs(pattern) else os.path.join(root, pattern) for path in glob.iglob(effective, recursive=True): full = os.path.abspath(path) if full in seen: continue if lowered_contains and not any(text in os.path.basename(full).lower() or text in full.lower() for text in lowered_contains): continue if args.type == "f" and not os.path.isfile(full): continue if args.type == "d" and not os.path.isdir(full): continue seen.add(full) rows.append(full if args.absolute else os.path.relpath(full, root)) if args.sort: rows.sort() if args.limit > 0: rows = rows[:args.limit] for row in rows: print(row) return 0 if __name__ == "__main__": raise SystemExit(main())