making script compatible with zsh for absolutely no reason

This commit is contained in:
Jack
2020-04-09 01:04:10 +03:00
parent c0dda851d1
commit 08af5a567d
+223 -192
View File
@@ -2,7 +2,7 @@
# Push-button installer of macOS on VirtualBox # Push-button installer of macOS on VirtualBox
# (c) myspaghetti, licensed under GPL2.0 or higher # (c) myspaghetti, licensed under GPL2.0 or higher
# url: https://github.com/myspaghetti/macos-guest-virtualbox # url: https://github.com/myspaghetti/macos-guest-virtualbox
# version 0.89.5 # version 0.89.6
# Dependencies: bash coreutils gzip unzip wget xxd dmg2img # Dependencies: bash coreutils gzip unzip wget xxd dmg2img
# Supported versions: # Supported versions:
@@ -102,19 +102,33 @@ clear_input_buffer_then_read
# check dependencies # check dependencies
function check_bash_version() { function check_shell() {
if [[ -z "${BASH_VERSION}" ]]; then if [[ "${SHELL}" =~ /bash ]]; then
echo "Can't determine BASH_VERSION. Exiting." if [[ -z "${BASH_VERSION}" ]]; then
exit echo "Can't determine BASH_VERSION. Exiting."
elif [[ "${BASH_VERSION:0:1}" -lt 4 ]]; then exit
echo "Please run this script on Bash 4.3 or higher." elif [[ "${BASH_VERSION:0:1}" -lt 4 ]]; then
if [[ -n "$(sw_vers 2>/dev/null)" ]]; then echo "Please run this script on Bash 4.3 or higher."
echo "macOS detected. Make sure the script is not running on" if [[ -n "$(sw_vers 2>/dev/null)" ]]; then
echo "the default /bin/bash which is version 3." echo "macOS detected. Make sure the script is not running on"
echo "the default /bin/bash which is version 3."
fi
exit
elif [[ "${BASH_VERSION:0:1}" -eq 4 && "${BASH_VERSION:2:1}" -le 2 ]]; then
echo "Please run this script on Bash 4.3 or higher."
exit
fi fi
exit elif [[ "${SHELL}" =~ /zsh ]]; then
elif [[ "${BASH_VERSION:0:1}" -eq 4 && "${BASH_VERSION:2:1}" -le 2 ]]; then if [[ -z "${ZSH_VERSION}" ]]; then
echo "Please run this script on Bash 4.3 or higher." echo "Can't determine ZSH_VERSION. Exiting."
exit
elif [[ "${ZSH_VERSION:0:1}" -lt 5 ]]; then
echo "Please run this script on zsh 5 or higher."
exit
fi
setopt extendedglob sh_word_split ksh_arrays posix_argzero
else
echo "Can't determine SHELL. Exiting."
exit exit
fi fi
} }
@@ -176,7 +190,8 @@ if [[ -z "$(echo "xxd" | xxd -p 2>/dev/null)" || \
fi fi
# wget supports --show-progress from version 1.16 # wget supports --show-progress from version 1.16
if [[ "$(wget --version 2>/dev/null | head -n 1)" =~ 1\.1[6-9]|1\.2[0-9] ]]; then regex='1\.1[6-9]|1\.2[0-9]'
if [[ "$(wget --version 2>/dev/null | head -n 1)" =~ ${regex} ]]; then
wgetargs="--quiet --continue --show-progress" # pretty wgetargs="--quiet --continue --show-progress" # pretty
else else
wgetargs="--continue" # ugly wgetargs="--continue" # ugly
@@ -342,10 +357,9 @@ if [[ -n "$(VBoxManage showvminfo "${vm_name}" 2>/dev/null)" ]]; then
echo '' echo ''
echo 'A virtual machine named "'"${vm_name}"'" already exists.' echo 'A virtual machine named "'"${vm_name}"'" already exists.'
printf "${warning_color}"'Delete existing virtual machine "'"${vm_name}"'"?'"${default_color}" printf "${warning_color}"'Delete existing virtual machine "'"${vm_name}"'"?'"${default_color}"
delete="" prompt_delete_y_n
read -n 1 -p ' [y/N] ' delete if [[ "${delete}" == "y" ]]; then
echo "" echo "Deleting ${vm_name} virtual machine."
if [[ "${delete,,}" == "y" ]]; then
VBoxManage unregistervm "${vm_name}" --delete VBoxManage unregistervm "${vm_name}" --delete
else else
echo "" echo ""
@@ -653,10 +667,9 @@ print_dimly "stage: create_install_vdi"
if [[ -w "Install ${macOS_release_name}.vdi" ]]; then if [[ -w "Install ${macOS_release_name}.vdi" ]]; then
echo '"'"Install ${macOS_release_name}.vdi"'" virtual disk image exists.' echo '"'"Install ${macOS_release_name}.vdi"'" virtual disk image exists.'
printf "${warning_color}"'Delete "'"Install ${macOS_release_name}.vdi"'"?'"${default_color}" printf "${warning_color}"'Delete "'"Install ${macOS_release_name}.vdi"'"?'"${default_color}"
delete="" prompt_delete_y_n
read -n 1 -p " [y/N] " delete
echo "" echo ""
if [[ "${delete,,}" == "y" ]]; then if [[ "${delete}" == "y" ]]; then
if [[ "$( VBoxManage list runningvms )" =~ \""${vm_name}"\" ]]; if [[ "$( VBoxManage list runningvms )" =~ \""${vm_name}"\" ]];
then then
echo '"'"Install ${macOS_release_name}.vdi"'" may be deleted' echo '"'"Install ${macOS_release_name}.vdi"'" may be deleted'
@@ -753,6 +766,7 @@ fi
echo "Starting virtual machine ${vm_name}. This should take a couple of minutes." echo "Starting virtual machine ${vm_name}. This should take a couple of minutes."
( VBoxManage startvm "${vm_name}" >/dev/null 2>&1 ) ( VBoxManage startvm "${vm_name}" >/dev/null 2>&1 )
echo "While the script is running, please do not interact with the virtual machine." echo "While the script is running, please do not interact with the virtual machine."
[[ -z "${kscd}" ]] && declare_scancode_dict
prompt_lang_utils prompt_lang_utils
prompt_terminal_ready prompt_terminal_ready
print_dimly "Please wait" print_dimly "Please wait"
@@ -839,6 +853,7 @@ if [[ -n $(
fi fi
echo "The VM will boot from the populated installer base system virtual disk." echo "The VM will boot from the populated installer base system virtual disk."
( VBoxManage startvm "${vm_name}" >/dev/null 2>&1 ) ( VBoxManage startvm "${vm_name}" >/dev/null 2>&1 )
[[ -z "${kscd}" ]] && declare_scancode_dict
prompt_lang_utils prompt_lang_utils
prompt_terminal_ready prompt_terminal_ready
add_another_terminal add_another_terminal
@@ -929,10 +944,8 @@ else
fi fi
echo "" echo ""
printf "${warning_color}"'Delete temporary files?'"${default_color}" printf "${warning_color}"'Delete temporary files?'"${default_color}"
delete="" prompt_delete_y_n
read -n 1 -p " [y/N] " delete if [[ "${delete}" == "y" ]]; then
echo ""
if [[ "${delete,,}" == "y" ]]; then
rm "${macOS_release_name}_Apple"* \ rm "${macOS_release_name}_Apple"* \
"${macOS_release_name}_BaseSystem"* \ "${macOS_release_name}_BaseSystem"* \
"${macOS_release_name}_Install"* \ "${macOS_release_name}_Install"* \
@@ -969,17 +982,18 @@ patiently and, less than ten times, press enter when prompted.
The script is divided into stages. Stage titles may be given as command-line The script is divided into stages. Stage titles may be given as command-line
arguments for the script. When the script is run with no command-line arguments for the script. When the script is run with no command-line
arguments, each of the available stages except \"${low_contrast_color}documentation${default_color}\" and arguments, each of the available stages except \"${low_contrast_color}documentation${default_color}\" and
\"${low_contrast_color}troubleshoot${default_color}\" is executed in succession in the order listed: \"${low_contrast_color}troubleshoot${default_color}\" is performed in succession in the order listed:
${low_contrast_stages} ${low_contrast_stages}
The stage \"${low_contrast_color}documentation${default_color}\" and \"${low_contrast_color}troubleshoot${default_color}\" is only executed when it is Either of the stages \"${low_contrast_color}documentation${default_color}\" and \"${low_contrast_color}troubleshoot${default_color}\" is only performed when
specified as the first command-line argument, with all subsequent arguments it is specified as the first command-line argument, with all subsequent
ignored. When specified after any argument, \"${low_contrast_color}documentation${default_color}\" and \"${low_contrast_color}troubleshoot${default_color}\" arguments ignored. When specified after any argument, either of \"${low_contrast_color}documentation${default_color}\"
is ignored. and \"${low_contrast_color}troubleshoot${default_color}\" is ignored.
The four stages \"${low_contrast_color}check_bash_version${default_color}\", \"${low_contrast_color}check_gnu_coreutils_prefix${default_color}\", The stage \"${low_contrast_color}check_shell${default_color}\" is always performed when the script loads.
\"${low_contrast_color}set_variables${default_color}\", and \"${low_contrast_color}check_dependencies${default_color}\" are always performed when any stage The stages \"${low_contrast_color}check_gnu_coreutils_prefix${default_color}\", \"${low_contrast_color}set_variables${default_color}\", and
title other than \"${low_contrast_color}documentation${default_color}\" or \"${low_contrast_color}troubleshoot${default_color}\" is specified as the first \"${low_contrast_color}check_dependencies${default_color}\" are always performed when any stage title other than
\"${low_contrast_color}documentation${default_color}\" or \"${low_contrast_color}troubleshoot${default_color}\" is specified as the first
argument, and the rest of the stages are parsed only after the checks pass. argument, and the rest of the stages are parsed only after the checks pass.
${highlight_color}EXAMPLES${default_color} ${highlight_color}EXAMPLES${default_color}
@@ -1162,140 +1176,143 @@ function sleep() {
# Virtualbox Mac scancodes found here: # Virtualbox Mac scancodes found here:
# https://wiki.osdev.org/PS/2_Keyboard#Scan_Code_Set_1 # https://wiki.osdev.org/PS/2_Keyboard#Scan_Code_Set_1
# First half of hex code - press, second half - release, unless otherwise specified # First half of hex code - press, second half - release, unless otherwise specified
declare -A kscd=( function declare_scancode_dict() {
["ESC"]="01 81" declare -gA kscd
["1"]="02 82" kscd=(
["2"]="03 83" ["ESC"]="01 81"
["3"]="04 84" ["1"]="02 82"
["4"]="05 85" ["2"]="03 83"
["5"]="06 86" ["3"]="04 84"
["6"]="07 87" ["4"]="05 85"
["7"]="08 88" ["5"]="06 86"
["8"]="09 89" ["6"]="07 87"
["9"]="0A 8A" ["7"]="08 88"
["0"]="0B 8B" ["8"]="09 89"
["-"]="0C 8C" ["9"]="0A 8A"
["="]="0D 8D" ["0"]="0B 8B"
["BKSP"]="0E 8E" ["-"]="0C 8C"
["TAB"]="0F 8F" ["="]="0D 8D"
["q"]="10 90" ["BKSP"]="0E 8E"
["w"]="11 91" ["TAB"]="0F 8F"
["e"]="12 92" ["q"]="10 90"
["r"]="13 93" ["w"]="11 91"
["t"]="14 94" ["e"]="12 92"
["y"]="15 95" ["r"]="13 93"
["u"]="16 96" ["t"]="14 94"
["i"]="17 97" ["y"]="15 95"
["o"]="18 98" ["u"]="16 96"
["p"]="19 99" ["i"]="17 97"
["["]="1A 9A" ["o"]="18 98"
["]"]="1B 9B" ["p"]="19 99"
["ENTER"]="1C 9C" ["["]="1A 9A"
["CTRLprs"]="1D" ["]"]="1B 9B"
["CTRLrls"]="9D" ["ENTER"]="1C 9C"
["a"]="1E 9E" ["CTRLprs"]="1D"
["s"]="1F 9F" ["CTRLrls"]="9D"
["d"]="20 A0" ["a"]="1E 9E"
["f"]="21 A1" ["s"]="1F 9F"
["g"]="22 A2" ["d"]="20 A0"
["h"]="23 A3" ["f"]="21 A1"
["j"]="24 A4" ["g"]="22 A2"
["k"]="25 A5" ["h"]="23 A3"
["l"]="26 A6" ["j"]="24 A4"
[";"]="27 A7" ["k"]="25 A5"
["'"]="28 A8" ["l"]="26 A6"
['`']="29 A9" [";"]="27 A7"
["LSHIFTprs"]="2A" ["'"]="28 A8"
["LSHIFTrls"]="AA" ['`']="29 A9"
['\']="2B AB" ["LSHIFTprs"]="2A"
["z"]="2C AC" ["LSHIFTrls"]="AA"
["x"]="2D AD" ['\']="2B AB"
["c"]="2E AE" ["z"]="2C AC"
["v"]="2F AF" ["x"]="2D AD"
["b"]="30 B0" ["c"]="2E AE"
["n"]="31 B1" ["v"]="2F AF"
["m"]="32 B2" ["b"]="30 B0"
[","]="33 B3" ["n"]="31 B1"
["."]="34 B4" ["m"]="32 B2"
["/"]="35 B5" [","]="33 B3"
["RSHIFTprs"]="36" ["."]="34 B4"
["RSHIFTrls"]="B6" ["/"]="35 B5"
["ALTprs"]="38" ["RSHIFTprs"]="36"
["ALTrls"]="B8" ["RSHIFTrls"]="B6"
["LALT"]="38 B8" ["ALTprs"]="38"
["SPACE"]="39 B9" ["ALTrls"]="B8"
[" "]="39 B9" ["LALT"]="38 B8"
["CAPS"]="3A BA" ["SPACE"]="39 B9"
["CAPSLOCK"]="3A BA" [" "]="39 B9"
["F1"]="3B BB" ["CAPS"]="3A BA"
["F2"]="3C BC" ["CAPSLOCK"]="3A BA"
["F3"]="3D BD" ["F1"]="3B BB"
["F4"]="3E BE" ["F2"]="3C BC"
["F5"]="3F BF" ["F3"]="3D BD"
["F6"]="40 C0" ["F4"]="3E BE"
["F7"]="41 C1" ["F5"]="3F BF"
["F8"]="42 C2" ["F6"]="40 C0"
["F9"]="43 C3" ["F7"]="41 C1"
["F10"]="44 C4" ["F8"]="42 C2"
["UP"]="E0 48 E0 C8" ["F9"]="43 C3"
["RIGHT"]="E0 4D E0 CD" ["F10"]="44 C4"
["LEFT"]="E0 4B E0 CB" ["UP"]="E0 48 E0 C8"
["DOWN"]="E0 50 E0 D0" ["RIGHT"]="E0 4D E0 CD"
["HOME"]="E0 47 E0 C7" ["LEFT"]="E0 4B E0 CB"
["END"]="E0 4F E0 CF" ["DOWN"]="E0 50 E0 D0"
["PGUP"]="E0 49 E0 C9" ["HOME"]="E0 47 E0 C7"
["PGDN"]="E0 51 E0 D1" ["END"]="E0 4F E0 CF"
["CMDprs"]="E0 5C" ["PGUP"]="E0 49 E0 C9"
["CMDrls"]="E0 DC" ["PGDN"]="E0 51 E0 D1"
# all codes below start with LSHIFTprs as commented in first item: ["CMDprs"]="E0 5C"
["!"]="2A 02 82 AA" # LSHIFTprs 1prs 1rls LSHIFTrls ["CMDrls"]="E0 DC"
["@"]="2A 03 83 AA" # all codes below start with LSHIFTprs as commented in first item:
["#"]="2A 04 84 AA" ["!"]="2A 02 82 AA" # LSHIFTprs 1prs 1rls LSHIFTrls
["$"]="2A 05 85 AA" ["@"]="2A 03 83 AA"
["%"]="2A 06 86 AA" ["#"]="2A 04 84 AA"
["^"]="2A 07 87 AA" ["$"]="2A 05 85 AA"
["&"]="2A 08 88 AA" ["%"]="2A 06 86 AA"
["*"]="2A 09 89 AA" ["^"]="2A 07 87 AA"
["("]="2A 0A 8A AA" ["&"]="2A 08 88 AA"
[")"]="2A 0B 8B AA" ["*"]="2A 09 89 AA"
["_"]="2A 0C 8C AA" ["("]="2A 0A 8A AA"
["+"]="2A 0D 8D AA" [")"]="2A 0B 8B AA"
["Q"]="2A 10 90 AA" ["_"]="2A 0C 8C AA"
["W"]="2A 11 91 AA" ["+"]="2A 0D 8D AA"
["E"]="2A 12 92 AA" ["Q"]="2A 10 90 AA"
["R"]="2A 13 93 AA" ["W"]="2A 11 91 AA"
["T"]="2A 14 94 AA" ["E"]="2A 12 92 AA"
["Y"]="2A 15 95 AA" ["R"]="2A 13 93 AA"
["U"]="2A 16 96 AA" ["T"]="2A 14 94 AA"
["I"]="2A 17 97 AA" ["Y"]="2A 15 95 AA"
["O"]="2A 18 98 AA" ["U"]="2A 16 96 AA"
["P"]="2A 19 99 AA" ["I"]="2A 17 97 AA"
["{"]="2A 1A 9A AA" ["O"]="2A 18 98 AA"
["}"]="2A 1B 9B AA" ["P"]="2A 19 99 AA"
["A"]="2A 1E 9E AA" ["{"]="2A 1A 9A AA"
["S"]="2A 1F 9F AA" ["}"]="2A 1B 9B AA"
["D"]="2A 20 A0 AA" ["A"]="2A 1E 9E AA"
["F"]="2A 21 A1 AA" ["S"]="2A 1F 9F AA"
["G"]="2A 22 A2 AA" ["D"]="2A 20 A0 AA"
["H"]="2A 23 A3 AA" ["F"]="2A 21 A1 AA"
["J"]="2A 24 A4 AA" ["G"]="2A 22 A2 AA"
["K"]="2A 25 A5 AA" ["H"]="2A 23 A3 AA"
["L"]="2A 26 A6 AA" ["J"]="2A 24 A4 AA"
[":"]="2A 27 A7 AA" ["K"]="2A 25 A5 AA"
['"']="2A 28 A8 AA" ["L"]="2A 26 A6 AA"
["~"]="2A 29 A9 AA" [":"]="2A 27 A7 AA"
["|"]="2A 2B AB AA" ['"']="2A 28 A8 AA"
["Z"]="2A 2C AC AA" ["~"]="2A 29 A9 AA"
["X"]="2A 2D AD AA" ["|"]="2A 2B AB AA"
["C"]="2A 2E AE AA" ["Z"]="2A 2C AC AA"
["V"]="2A 2F AF AA" ["X"]="2A 2D AD AA"
["B"]="2A 30 B0 AA" ["C"]="2A 2E AE AA"
["N"]="2A 31 B1 AA" ["V"]="2A 2F AF AA"
["M"]="2A 32 B2 AA" ["B"]="2A 30 B0 AA"
["<"]="2A 33 B3 AA" ["N"]="2A 31 B1 AA"
[">"]="2A 34 B4 AA" ["M"]="2A 32 B2 AA"
["?"]="2A 35 B5 AA" ["<"]="2A 33 B3 AA"
) [">"]="2A 34 B4 AA"
["?"]="2A 35 B5 AA"
)
}
function clear_input_buffer_then_read() { function clear_input_buffer_then_read() {
while read -d '' -r -t 0; do read -d '' -t 0.1 -n 10000; break; done while read -d '' -r -t 0; do read -d '' -t 0.1 -n 10000; break; done
@@ -1304,8 +1321,9 @@ function clear_input_buffer_then_read() {
# read variable kbstring and convert string to scancodes and send to guest vm # read variable kbstring and convert string to scancodes and send to guest vm
function send_keys() { function send_keys() {
scancode=$(for (( i=0; i < ${#kbstring}; i++ )); scancode=$(for (( i=0; i < ${#kbstring}; i++ )); do
do c[i]=${kbstring:i:1}; echo -n ${kscd[${c[i]}]}" "; done) c[${i}]=${kbstring:${i}:1}; echo -n ${kscd[${c[${i}]}]}" "
done)
VBoxManage controlvm "${vm_name}" keyboardputscancode ${scancode} 1>/dev/null 2>&1 VBoxManage controlvm "${vm_name}" keyboardputscancode ${scancode} 1>/dev/null 2>&1
} }
@@ -1373,35 +1391,49 @@ function would_you_like_to_know_less() {
fi fi
} }
function prompt_delete_y_n() {
delete=""
if [[ "${SHELL}" =~ /zsh ]]; then
read -s -q delete\?' [y/N] '
delete="${delete:l}"
elif [[ "${SHELL}" =~ /bash ]]; then
read -n 1 -p ' [y/N] ' delete
delete="${delete,,}"
fi
echo ""
}
# command-line argument processing # command-line argument processing
stages=' stages='
check_bash_version check_shell
check_gnu_coreutils_prefix check_gnu_coreutils_prefix
set_variables set_variables
welcome welcome
check_dependencies check_dependencies
prompt_delete_existing_vm prompt_delete_existing_vm
create_vm create_vm
prepare_macos_installation_files prepare_macos_installation_files
create_nvram_files create_nvram_files
create_macos_installation_files_viso create_macos_installation_files_viso
create_basesystem_vdi create_basesystem_vdi
create_target_vdi create_target_vdi
create_install_vdi create_install_vdi
configure_vm configure_vm
populate_virtual_disks populate_virtual_disks
populate_macos_target populate_macos_target
delete_temporary_files delete_temporary_files
documentation documentation
troubleshoot troubleshoot
' '
check_shell
stages_without_newlines="${stages//[$'\r\n']/}" stages_without_newlines="${stages//[$'\r\n']/}"
[[ "${1}" = "documentation" ]] && documentation && exit [[ "${1}" = "documentation" ]] && documentation && exit
if [[ "${1}" = "troubleshoot" ]]; then set_variables; check_dependencies >/dev/null; troubleshoot; exit; fi if [[ "${1}" = "troubleshoot" ]]; then set_variables; check_dependencies >/dev/null; troubleshoot; exit; fi
stages="${stages//documentation/}" # strip all occurrences of "documentation" stages_without_newlines="${stages//[$'\r\n']/ }" # replace newline with space character
stages="${stages//troubleshoot/}" # strip all occurrences of "troubleshoot" stages_without_newlines="${stages_without_newlines//documentation/}" # strip all occurrences of "documentation"
[[ -z "${1}" ]] && for stage in ${stages}; do ${stage}; done && exit stages_without_newlines="${stages_without_newlines//troubleshoot/}" # strip all occurrences of "troubleshoot"
[[ -z "${1}" ]] && for stage in ${stages_without_newlines}; do ${stage}; done && exit
# every stage name must be preceded and followed by a space character # every stage name must be preceded and followed by a space character
# for the command-line argument checking below to work # for the command-line argument checking below to work
for argument in $@; do for argument in $@; do
@@ -1415,7 +1447,6 @@ for argument in $@; do
exit exit
fi fi
done done
check_bash_version
check_gnu_coreutils_prefix check_gnu_coreutils_prefix
set_variables set_variables
check_dependencies check_dependencies