Skip to content

Instantly share code, notes, and snippets.

@tenox7
Created May 9, 2026 21:59
Show Gist options
  • Select an option

  • Save tenox7/8f6a89aac43464b5aa19bb99149bcc6d to your computer and use it in GitHub Desktop.

Select an option

Save tenox7/8f6a89aac43464b5aa19bb99149bcc6d to your computer and use it in GitHub Desktop.
zip2rar for macos with sandbox
#!/bin/bash
set -euo pipefail
usage() { cat >&2 <<'EOF'
usage: zip2rar [options] FILE.zip
--delete-source remove source zip after success
--keep-mac-metadata keep .DS_Store, ._*, __MACOSX, etc.
--no-sandbox skip sandbox-exec (debug only)
-f, --force overwrite destination
-h, --help this help
EOF
}
src="" delete_source=0 keep_meta=0 no_sandbox=0 force=0
while [ $# -gt 0 ]; do
case "$1" in
--delete-source) delete_source=1 ;;
--keep-mac-metadata) keep_meta=1 ;;
--no-sandbox) no_sandbox=1 ;;
-f|--force) force=1 ;;
-h|--help) usage; exit 0 ;;
--) shift; src="${1:-}"; break ;;
-*) echo "unknown flag: $1" >&2; usage; exit 2 ;;
*) src="$1" ;;
esac
shift
done
[ -z "$src" ] && { usage; exit 2; }
[ -f "$src" ] || { echo "not found: $src" >&2; exit 1; }
src_abs=$(cd "$(dirname "$src")" && pwd -P)/$(basename "$src")
dst_abs="${src_abs%.*}.rar"
[ -e "$dst_abs" ] && [ "$force" -eq 0 ] && {
echo "exists: $dst_abs (use --force)" >&2
exit 1
}
rar_bin=$(command -v rar) || { echo "rar not in PATH" >&2; exit 1; }
rar_bin_real=$(readlink -f "$rar_bin" 2>/dev/null || echo "$rar_bin")
license=""
for cand in \
"$HOME/.rarreg.key" \
"$(dirname "$rar_bin_real")/rarreg.key" \
"$(dirname "$rar_bin_real")/../etc/rarreg.key" \
"/etc/rarreg.key"; do
[ -f "$cand" ] || continue
license=$(cd "$(dirname "$cand")" && pwd -P)/$(basename "$cand")
break
done
[ -z "$license" ] && echo "warning: rarreg.key not found, rar will run unregistered" >&2
tmp=$(mktemp -d -t zip2rar.XXXXXX)
tmp=$(cd "$tmp" && pwd -P)
work="$tmp/work"
mkdir "$work"
done_flag=0
cleanup() {
local rc=$?
rm -rf "$tmp"
[ "$done_flag" -eq 0 ] && [ -e "$dst_abs" ] && rm -f "$dst_abs"
return "$rc"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
sandbox=()
if [ "$no_sandbox" -eq 0 ]; then
profile="$tmp/profile.sb"
src_dir=$(dirname "$src_abs")
dst_dir=$(dirname "$dst_abs")
cat > "$profile" <<EOF
(version 1)
(allow default)
(deny network*)
(allow network* (local ip) (local unix-socket))
(deny file-write*)
(allow file-write*
(subpath "$tmp")
(subpath "/private/var/folders")
(subpath "/private/tmp")
(subpath "/private/var/tmp")
(literal "$dst_abs")
(literal "/dev/null")
(literal "/dev/stdout")
(literal "/dev/stderr")
(literal "/dev/dtracehelper")
(literal "/dev/tty"))
EOF
sandbox=(sandbox-exec -f "$profile")
fi
"${sandbox[@]}" /bin/bash -e -c '
work=$1 src=$2 dst=$3 keep=$4
cd "$work"
echo "==> extract"
unzip -o "$src"
[ "$keep" -eq 0 ] && {
echo "==> cleanup"
find . -type d \( \
-name __MACOSX -o -name .Spotlight-V100 -o -name .fseventsd -o \
-name .Trashes -o -name .TemporaryItems -o \
-name .DocumentRevisions-V100 -o \
-name .AppleDouble -o -name .AppleDB -o -name .AppleDesktop -o \
-name "Network Trash Folder" -o -name "Temporary Items" -o \
-name "\$RECYCLE.BIN" -o -name "\$Recycle.bin" -o \
-name "System Volume Information" \
\) -prune -print -exec rm -rf {} +
find . -type f \( \
-name .DS_Store -o -name "._*" -o \
-name .VolumeIcon.icns -o -name .apdisk -o -name .localized -o \
-name ".com.apple.timemachine.*" -o \
-name .com.apple.smb.streams.ok -o \
-name "Thumbs.db*" -o -name Desktop.ini -o \
-name $'\''Icon\r'\'' \
\) -print -delete
}
echo "==> archive"
rar a -r -rr -m5 -md1g -mt16 -ol -y -o+ -idc "$dst" .
' _ "$work" "$src_abs" "$dst_abs" "$keep_meta"
[ -f "$dst_abs" ] || { echo "rar not created: $dst_abs" >&2; exit 1; }
echo "verifying rar..."
rar t "$dst_abs" >/dev/null || { echo "rar integrity failed" >&2; exit 1; }
done_flag=1
[ "$delete_source" -eq 1 ] && { rm -f "$src_abs"; echo "removed: $src_abs"; }
echo "done: $dst_abs"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment