#!/bin/sh # mktemp [-d] [template] mktemp() ( set -C umask 077 OPTIND=1 dir= while getopts :d opt ; do case $opt in (d) dir=1 ;; ('?') printf >&2 'mktemp: Invalid option -%s\n' "$OPTARG" return 2 ;; esac done shift "$(( OPTIND - 1 ))" template=${1-${TMPDIR:-/tmp}/tmp.XXXXXXXXXX} case $template in (*XXXXXX) ;; (*) printf >&2 'mktemp: Template must end with at least 6 X characters\n' return 2 ;; esac placeholder=${template##*[!X]} base=${template%"$placeholder"} retries=64 while [ "$retries" -gt 0 ] ; do placeholder=$(printf "$( awk -v n="$placeholder" -v i="$retries" ' BEGIN { srand(); srand(srand() * i); for (i = 0; i < length(n); ++i) { r = int(62 * rand()); if (r < 10) printf("%s", r); # 0-9 else if (r < 36) printf("\\%03o", r - 10 + 97); # a-z else printf("\\%03o", r - 36 + 65); # A-Z } } ' )" ) if [ "$dir" = 1 ] ; then if mkdir "$base$placeholder" 2>/dev/null ; then printf '%s\n' "$base$placeholder" return 0 fi else if 2>/dev/null >"$base$placeholder" ; then printf '%s\n' "$base$placeholder" return 0 fi fi retries=$(( retries - 1 )) done if [ "$dir" = 1 ] ; then printf >&2 'mktemp: Failed to create directory via template %s\n' "$template" else printf >&2 'mktemp: Failed to create file via template %s\n' "$template" fi return 1 )