Skip to content

Instantly share code, notes, and snippets.

@td-shi
Created August 4, 2026 06:45
Show Gist options
  • Select an option

  • Save td-shi/7bff5ca5f270a1453f31d73b9c5b12e4 to your computer and use it in GitHub Desktop.

Select an option

Save td-shi/7bff5ca5f270a1453f31d73b9c5b12e4 to your computer and use it in GitHub Desktop.
This script creates or extracts the crypted archive file(s).
#!/bin/sh
# -*- coding:utf-8 -*-
# === Initialize shell environment =============================================
#set -u # Just stop undefined values.
#set -e # Just stop error.
#set -x # Debug running command.
umask 0022
export LC_ALL=C
export LANG=C
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin:${PATH+:}${PATH-}"
type command >/dev/null 2>&1 && type getconf >/dev/null 2>&1 &&
PATH="$(command -p getconf PATH):${PATH}"
export PATH
export UNIX_STD=2003 # to make HP-UX conform to POSIX
# === Define the functions for printing usage and error message ================
usage_and_exit(){
cat <<-"USAGE" 1>&2
# About
This script creates or extracts the crypted archive file(s).
This script require the openssl command.
You must always specify either -x or -c; they can not be specified at the same time.
# Usage
## Command
cryptar.sh -c -o <output_name>[.tar.gz.enc] <file...> # Creating.
cryptar.sh -x -o <output_dir> <file> # Extracting.
## Options
- -h |--help |--version
+ This help.
- -c
+ Creating archive file.
- -o
+ The output name or directory.
- -x
+ Eextracting archive file.
# Version
2026-08-04 0.01
# LICENSE
[CC0(Public domain)](https://creativecommons.org/publicdomain/zero/1.0/legalcode)
# Author
2026 td-shi
USAGE
exit 1
}
error_exit() {
${2+:} false && echo "${0##*/}: $2" 1>&2
exit "$1"
}
# === Initialize parameters ====================================================
PERMIT_EXTRACT="0"
PERMIT_CREATE="0"
OUTPUT_PATH=""
PASSWORD=""
END_STATUS="0"
GUARD=""
# === Confirm that the required commands exist =================================
if type tar >/dev/null 2>&1; then
:
else
error_exit 1 'Require the tar command.'
fi
if type openssl >/dev/null 2>&1; then
:
else
error_exit 1 'Require the openssl command.'
fi
# === Print usage and exit if one of the help options is set ===================
case "$# ${1:-}" in
'1 -h'|'1 --help'|'1 --version') usage_and_exit;;
esac
# === Read options =============================================================
while :; do
case "${1:-}" in
-x)
PERMIT_EXTRACT="1"
shift
;;
-c)
PERMIT_CREATE="1"
shift
;;
-o)
OUTPUT_PATH=$(printf '%s' "${2:-}" | tr -d '\n')
shift 2
;;
--|-)
shift 1
;;
--*|-*)
error_exit 1 'Invalid option'
;;
*)
break
;;
esac
done
# === Require parameters check =================================================
if [ "_1" = "_${PERMIT_CREATE}" ] && [ "_1" = "_${PERMIT_EXTRACT}" ] ; then
error_exit 1 'Only one of the options, -x or -c.'
elif [ "_0" = "_${PERMIT_CREATE}" ] && [ "_0" = "_${PERMIT_EXTRACT}" ]; then
error_exit 1 'Require the one of the options, -x or -c.'
elif [ "_1" = "_${PERMIT_CREATE}" ] && [ 1 -gt "$#" ]; then
error_exit 1 'No files or directory.'
elif [ "_1" = "_${PERMIT_EXTRACT}" ] ; then
if [ 1 -ne "$#" ] ; then
error_exit 1 'So many or too few, files or directory.'
elif [ ! -f "$1" ] ; then
error_exit 1 'Not found the file.'
fi
else
:
fi
# === Last parameter ===========================================================
# === Define funcitons =========================================================
ask_password() {
recover() {
stty echo
printf "\n" 1>&2
exit 1
}
printf "Password: " 1>&2
trap recover HUP INT TERM
stty -echo
read -r PASSWORD
stty echo
printf "\n" 1>&2
trap - HUP INT TERM
}
encrypt() {
outp=$1
shift
tar czf - "$@" | openssl enc -e -aes-256-cbc -pbkdf2 -out "${outp}" -pass env:PASSWORD
}
decrypt() {
outp=$1
file=$2
openssl enc -d -aes-256-cbc -pbkdf2 -in "${file}" -pass env:PASSWORD | tar xzf - -C "${outp}"
}
# === Main routine =============================================================
while [ 8 -gt ${#PASSWORD} ] ; do
printf "%s\n" "At least 8 characters" 1>&2
ask_password
GUARD="${GUARD}X"
if [ 3 -lt ${#GUARD} ] ; then
error_exit 1 "Illegal input loop."
fi
done
if [ "_1" = "_${PERMIT_CREATE}" ] ; then
if [ -z "${OUTPUT_PATH}" ] ; then
OUTPUT_PATH="${1%.*}.tar.gz.enc"
fi
export PASSWORD
encrypt "${OUTPUT_PATH}" "$@"
END_STATUS=$?
unset PASSWORD
if [ 0 -eq "${END_STATUS}" ] ; then printf "%s\n" "Crypted ${OUTPUT_PATH}" 1>&2; fi
elif [ "_1" = "_${PERMIT_EXTRACT}" ] ; then
if [ -z "${OUTPUT_PATH}" ] ; then
OUTPUT_PATH="./"
fi
if [ ! -d "${OUTPUT_PATH}" ] ; then
error_exit 1 "Not found ${OUTPUT_PATH}"
fi
export PASSWORD
decrypt "${OUTPUT_PATH}" "${1}"
END_STATUS=$?
unset PASSWORD
if [ 0 -eq "${END_STATUS}" ] ; then printf "%s\n" "Extracted ${OUTPUT_PATH}" 1>&2; fi
else
:
fi
# === End shell script =========================================================
exit "${END_STATUS}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment