hardlink everything. I'm lazy
Authored by
mfwolffe <wolffemf@dukes.jmu.edu>
- SHA
280bdf6ae9c28b6a3d228a2f6d92ae7947a942f8- Parents
-
fc2bb4b - Tree
d43fb8b
280bdf6
280bdf6ae9c28b6a3d228a2f6d92ae7947a942f8fc2bb4b
d43fb8b| Status | File | + | - |
|---|---|---|---|
| A |
fish/functions/hardlink_all.fish
|
64 | 0 |
fish/functions/hardlink_all.fishadded@@ -0,0 +1,64 @@ | ||
| 1 | +## Hardlink every regular file from SRC to DST (non-recursive; includes dotfiles, skips dirs) | |
| 2 | +# | |
| 3 | +function hardlink_all --description "Hardlink every file from SRC to DST (includes dotfiles, skips dirs)" | |
| 4 | + set -l USAGE "Usage: hardlink_all SRC DST\n\nLinks: regular files only (top-level). Includes dotfiles. Creates DST if missing.\nNote: Hardlinks must be on the same filesystem." | |
| 5 | + | |
| 6 | + if test (count $argv) -lt 1 -o "$argv[1]" = "-h" -o "$argv[1]" = "--help" | |
| 7 | + echo -e $USAGE | |
| 8 | + return 0 | |
| 9 | + end | |
| 10 | + | |
| 11 | + if test (count $argv) -ne 2 | |
| 12 | + echo -e $USAGE >&2 | |
| 13 | + return 1 | |
| 14 | + end | |
| 15 | + | |
| 16 | + set -l src "$argv[1]" | |
| 17 | + set -l dst "$argv[2]" | |
| 18 | + | |
| 19 | + if not test -d "$src" | |
| 20 | + echo "hardlink_all: SRC is not a directory: $src" >&2 | |
| 21 | + return 1 | |
| 22 | + end | |
| 23 | + | |
| 24 | + # Ensure destination directory exists | |
| 25 | + mkdir -p "$dst" ^/dev/null | |
| 26 | + if not test -d "$dst" | |
| 27 | + echo "hardlink_all: failed to create DST: $dst" >&2 | |
| 28 | + return 1 | |
| 29 | + end | |
| 30 | + | |
| 31 | + # Best-effort filesystem check (hardlinks can't cross filesystems) | |
| 32 | + set -l srcfs (df -P "$src" | tail -1 | awk '{print $1}') | |
| 33 | + set -l dstfs (df -P "$dst" | tail -1 | awk '{print $1}') | |
| 34 | + if test -n "$srcfs" -a -n "$dstfs" -a "$srcfs" != "$dstfs" | |
| 35 | + echo "hardlink_all: SRC and DST are on different filesystems ($srcfs ≠ $dstfs); hardlinks will fail." >&2 | |
| 36 | + return 1 | |
| 37 | + end | |
| 38 | + | |
| 39 | + set -l count 0 | |
| 40 | + set -l fail 0 | |
| 41 | + | |
| 42 | + # Top-level files, including dotfiles; exclude '.' and '..' | |
| 43 | + set -l files $src/* | |
| 44 | + set -l dot1 $src/.[!.]* | |
| 45 | + set -l dot2 $src/..?* | |
| 46 | + | |
| 47 | + for f in $files $dot1 $dot2 | |
| 48 | + if test -f "$f" | |
| 49 | + ln -f "$f" "$dst/"; or begin | |
| 50 | + echo "hardlink_all: failed to link: $f" >&2 | |
| 51 | + set fail 1 | |
| 52 | + end | |
| 53 | + set count (math $count + 1) | |
| 54 | + end | |
| 55 | + end | |
| 56 | + | |
| 57 | + if test $count -eq 0 | |
| 58 | + echo "hardlink_all: nothing to link (no regular files found in $src)." | |
| 59 | + else | |
| 60 | + echo "hardlink_all: linked $count file(s) from $src → $dst" | |
| 61 | + end | |
| 62 | + | |
| 63 | + return $fail | |
| 64 | +end | |