diff --git a/.gemini/settings.json b/.gemini/settings.json new file mode 100644 index 0000000..68337d3 --- /dev/null +++ b/.gemini/settings.json @@ -0,0 +1 @@ +{ "contextFileName": "AGENTS.md" } diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e975061 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,34 @@ +## Installation and Environment + +This is a set of dotfiles and utilities for setting up my personal environment +on POSIX-style environments. It is cloned from github and installed from the +`install.sh` script. + +It mostly relies on symlinking dotfiles and other resources into the appropriate +locations, bnut also installs dependencies in various ways. + +I primarily target Debian Linux-based (Debian, Ubuntu, and Kali Linux) systems +as well as MacOS. Other platforms are lower priorities. Shell scripts ending +in `.sh` should use only POSIX features unless there is a shebang line at the +beginning suggesting a different shell will be used. + +`zsh` and `fish` are the key interactive shells to be configured, but `bash` +may also be used at times. + +## Notes on Security Issues + +It is safe to have scripts and tools re-invoke themselves with sudo when they +require elevated privileges, as these are my own. Do not attempt to remove +these use cases. + +## Making Changes + +**IMPORTANT**: Only make those changes which are explicitly requested. If you +identify other issues, notify me about them, but do not suggest changes until I +ask for them. + +When making large changes, explain your chain of thought transparently and +explain solution design. + +If making changes that affects how the user installs the tools, update +`README.md` accordingly. diff --git a/bin/checksec.sh b/bin/checksec.sh index dd1f72e..473aeae 100755 --- a/bin/checksec.sh +++ b/bin/checksec.sh @@ -835,14 +835,14 @@ case "$1" in fi cd /proc N=$2 - if [ -d $N ] ; then + if [ -d "$N" ] ; then # read permissions? - if [ ! -r $N/exe ] ; then + if [ ! -r "$N/exe" ] ; then if !(root_privs) ; then - printf "\033[31mNo read permissions for '/proc/$N/exe' (run as root).\033[m\n\n" + printf "\033[31mNo read permissions for '/proc/%s/exe' (run as root).\033[m\n\n" "$N" exit 1 fi - if [ ! `readlink $N/exe` ] ; then + if [ ! "$(readlink "$N/exe")" ] ; then printf "\033[31mPermission denied. Requested process ID belongs to a kernel thread.\033[m\n\n" exit 1 fi @@ -860,9 +860,9 @@ case "$1" in printf "\033[31mError: libc not found.\033[m\n\n" exit 1 fi - printf "* Process name (PID) : %s (%d)\n" `head -1 $N/status | cut -b 7-` $N - FS_chk_func_libc=( $(readelf -s $FS_libc | grep _chk@@ | awk '{ print $8 }' | cut -c 3- | sed -e 's/_chk@.*//') ) - FS_functions=( $(readelf -s $2/exe | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//') ) + printf "* Process name (PID) : %s (%d)\n" "$(head -1 "$N/status" | cut -b 7-)" "$N" + FS_chk_func_libc=( $(readelf -s "$FS_libc" | grep _chk@@ | awk '{ print $8 }' | cut -c 3- | sed -e 's/_chk@.*//') ) + FS_functions=( $(readelf -s "$2/exe" | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//') ) FS_libc_check FS_binary_check diff --git a/bin/google-chrome-noroot b/bin/google-chrome-noroot index 77c29cc..1d98f13 100755 --- a/bin/google-chrome-noroot +++ b/bin/google-chrome-noroot @@ -3,8 +3,12 @@ CHROME=`which google-chrome` if [ `id -u` != "0" ] ; then - exec $CHROME "$@" + exec "$CHROME" "$@" fi -CMD="${CHROME} --user-data-dir=${HOME}/.chrome-data-dir \"$@\"" -su -c "${CMD}" chromeuser +args=() +for x in "$@"; do + args+=("$(printf %q "$x")") +done + +su -c "$CHROME --user-data-dir=${HOME}/.chrome-data-dir ${args[*]}" chromeuser diff --git a/bin/i3lock.sh b/bin/i3lock.sh index 42260c5..06de9aa 100755 --- a/bin/i3lock.sh +++ b/bin/i3lock.sh @@ -2,6 +2,7 @@ LOCKTIME="${SCREENSAVER_MIN:-5}" LOCKER="i3lock -c 000000" # intentionally want word splitting below +# do not quote this /usr/bin/xss-lock -- ${LOCKER} & exec /usr/bin/xautolock \ -time "${LOCKTIME}" \ diff --git a/bin/install_package.sh b/bin/install_package.sh index 9b4a542..8b1abcc 100644 --- a/bin/install_package.sh +++ b/bin/install_package.sh @@ -42,7 +42,7 @@ install_package() { return 1 fi echo "Installing '$package' using apt-get..." - sudo apt-get install -y "$package" + sudo apt-get install -y -- "$package" return 0 elif command -v yum &> /dev/null; then package=$(package_alias yum "${package}") @@ -51,7 +51,7 @@ install_package() { return 1 fi echo "Installing '$package' using yum..." - sudo yum install -y "$package" + sudo yum install -y -- "$package" return 0 elif command -v pacman &> /dev/null; then package=$(package_alias pacman "${package}") @@ -60,7 +60,7 @@ install_package() { return 1 fi echo "Installing '$package' using pacman..." - sudo pacman -S "$package" + sudo pacman -S -- "$package" return 0 # For macOS, assume Homebrew is installed elif command -v brew &> /dev/null; then @@ -70,7 +70,7 @@ install_package() { return 1 fi echo "Installing '$package' using Homebrew..." - brew install "$package" + brew install -- "$package" return 0 else echo "Error: No suitable package manager found." diff --git a/bin/install_tool b/bin/install_tool index 3c06f54..7af14d1 100755 --- a/bin/install_tool +++ b/bin/install_tool @@ -2,6 +2,9 @@ set -ue +TMPDIR=$(mktemp -d) +trap 'rm -rf -- "${TMPDIR}"' EXIT + REINSTALL=0 PACKAGES=1 @@ -72,8 +75,7 @@ function download { SRC=${1} DST=${2} echo -n "Downloading ${SRC} to ${DST}..." >&2 - # TODO: consider curl instead? - wget --no-server-response -q -O "${DST}" --content-disposition "${SRC}" + curl -fL -o "${DST}" "${SRC}" echo " done." >&2 } @@ -118,6 +120,13 @@ function deb_only { fi } +function get_latest_github_release_url { + local repo="$1" + local glob="$2" + curl -s "https://api.github.com/repos/${repo}/releases/latest" | \ + jq -r ".assets[] | select(.name|test(\"${glob}\")) | .browser_download_url" +} + function require_pipx { command -v pipx >/dev/null 2>&1 || die "Requires pipx" } @@ -125,16 +134,17 @@ function require_pipx { # Begin main tool selection case ${TOOL} in john) + deb_only makedest_or_die install_pkgs libssl-dev git build-essential yasm libgmp-dev libpcap-dev \ pkg-config libbz2-dev libopenmpi-dev openmpi-bin libnss3-dev \ libkrb5-dev libgmp-dev - jtemp=$(mktemp -d) + jtemp="${TMPDIR}/john" + mkdir -p "${jtemp}" git clone https://github.com/magnumripper/JohnTheRipper.git "${jtemp}/john" - cd "${jtemp}/john/src" + cd "${jtemp}/john/src" || exit ./configure && make -sj2 cp -r "${jtemp}"/john/run/* "${DESTDIR}" - rm -rf "${jtemp}" # Persistent files mkdir -p "${HOME}/.john" touch "${HOME}/.john/john.pot" @@ -144,15 +154,15 @@ case ${TOOL} in wordlists) makedest download \ - http://downloads.skullsecurity.org/passwords/rockyou.txt.bz2 \ + "http://downloads.skullsecurity.org/passwords/rockyou.txt.bz2" \ "${DESTDIR}/rockyou.txt.bz2" bunzip2 "${DESTDIR}/rockyou.txt.bz2" download \ - http://downloads.skullsecurity.org/passwords/phpbb.txt.bz2 \ + "http://downloads.skullsecurity.org/passwords/phpbb.txt.bz2" \ "${DESTDIR}/phpbb.txt.bz2" bunzip2 "${DESTDIR}/phpbb.txt.bz2" download \ - http://downloads.skullsecurity.org/passwords/hak5.txt.bz2 \ + "http://downloads.skullsecurity.org/passwords/hak5.txt.bz2" \ "${DESTDIR}/hak5.txt.bz2" bunzip2 "${DESTDIR}/hak5.txt.bz2" ;; @@ -165,19 +175,15 @@ case ${TOOL} in gcloud) makedest_or_die gbase="https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/" - # TODO: find a way to make this version independent - gsdk="google-cloud-sdk-385.0.0-linux-x86_64.tar.gz" - download "${gbase}${gsdk}" /tmp/gcloud.tar.gz - tar zxf /tmp/gcloud.tar.gz --strip-components=1 -C "${DESTDIR}" - rm /tmp/gcloud.tar.gz + gsdk=$(curl -s https://cloud.google.com/sdk/docs/install-sdk | grep -o "google-cloud-sdk-[0-9.]*-linux-x86_64.tar.gz" | head -n 1) + download "${gbase}${gsdk}" "${TMPDIR}/gcloud.tar.gz" + tar zxf "${TMPDIR}/gcloud.tar.gz" --strip-components=1 -C "${DESTDIR}" add_bin_symlink bin/gcloud ;; android-sdk) - # TODO: find a way to make this version independent - asdk="https://dl.google.com/android/repository/platform-tools_r31.0.2-linux.zip" - download ${asdk} /tmp/android-tools.zip - unzip -d "${DESTDIR}" /tmp/android-tools.zip - rm /tmp/android-tools.zip + asdk=$(curl -s https://developer.android.com/studio/releases/platform-tools | grep -o "https://dl.google.com/android/repository/platform-tools_r[0-9.]*-linux.zip" | head -n 1) + download "${asdk}" "${TMPDIR}/android-tools.zip" + unzip -d "${DESTDIR}" "${TMPDIR}/android-tools.zip" # Install components "${DESTDIR}/tools/bin/sdkmanager" "emulator" "platform-tools" ;; @@ -198,12 +204,10 @@ case ${TOOL} in ;; mitmproxy) makedest_or_die - ver=$(python3 -c 'from urllib import request; import json; print(json.load(request.urlopen("https://api.github.com/repos/mitmproxy/mitmproxy/releases/latest"))["tag_name"].replace("v",""))') download \ - "https://snapshots.mitmproxy.org/${ver}/mitmproxy-${ver}-linux.tar.gz" \ - /tmp/mitmproxy.tar.gz - tar zx -C "${DESTDIR}" -f /tmp/mitmproxy.tar.gz - rm /tmp/mitmproxy.tar.gz + "$(get_latest_github_release_url "mitmproxy/mitmproxy" ".*-linux\\.tar\\.gz")" \ + "${TMPDIR}/mitmproxy.tar.gz" + tar zx -C "${DESTDIR}" -f "${TMPDIR}/mitmproxy.tar.gz" add_bin_symlink mitmproxy add_bin_symlink mitmweb add_bin_symlink mitmdump @@ -211,37 +215,37 @@ case ${TOOL} in esp) makedest_or_die src="https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-61-gab8375a-5.2.0.tar.gz" - download ${src} /tmp/esp32.tar.gz - tar zx -C "${DESTDIR}" -f /tmp/esp32.tar.gz - rm /tmp/esp32.tar.gz + download "${src}" "${TMPDIR}/esp32.tar.gz" + tar zx -C "${DESTDIR}" -f "${TMPDIR}/esp32.tar.gz" git clone --recursive https://github.com/espressif/esp-idf.git "${DESTDIR}/esp-idf" ;; dex2jar) makedest_or_die src="https://github.com/pxb1988/dex2jar/releases/download/v2.4/dex-tools-v2.4.zip" - download ${src} /tmp/dex2jar.zip - tmpd=$(mktemp -d) - unzip -d "${tmpd}" /tmp/dex2jar.zip + download "${src}" "${TMPDIR}/dex2jar.zip" + tmpd="${TMPDIR}/dex2jar" + mkdir -p "${tmpd}" + unzip -d "${tmpd}" "${TMPDIR}/dex2jar.zip" mv "${tmpd}"/dex-tools-*/* "${DESTDIR}" - rm /tmp/dex2jar.zip - rm -rf "${tmpd}" rm "${DESTDIR}"/*.bat chmod +x "${DESTDIR}"/*.sh ;; proxmark3) + deb_only install_pkgs p7zip git build-essential libreadline5 libreadline-dev \ libusb-0.1-4 libusb-dev libqt4-dev perl pkg-config wget libncurses5-dev \ gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib src="https://github.com/Proxmark/proxmark3.git" git clone "${src}" "${DESTDIR}" - cd "${DESTDIR}" + cd "${DESTDIR}" || exit make -sj2 check_sudo && sudo /bin/sh -c \ "cp -rf driver/78-mm-usb-device-blacklist.rules \ - /etc/udev/rules.d/77-mm-usb-device-blacklist.rules && + /etc/udev/rules.d/77-mm-usb-device-blacklist.rules &&\ udevadm control --reload-rules" ;; pm3iceman) + deb_only # arch: # sudo pacman -Syu git base-devel readline bzip2 lz4 arm-none-eabi-gcc arm-none-eabi-newlib qt5-base bluez python gd --needed install_pkgs git ca-certificates build-essential pkg-config \ @@ -249,19 +253,20 @@ case ${TOOL} in libbz2-dev libbluetooth-dev libpython3-dev libssl-dev src="https://github.com/RfidResearchGroup/proxmark3.git" git clone "${src}" "${DESTDIR}" - cd "${DESTDIR}" + cd "${DESTDIR}" || exit make clean && make -sj2 check_sudo && sudo /bin/sh -c \ "cp -rf ./driver/77-pm3-usb-device-blacklist.rules \ - /etc/udev/rules.d/77-pm3-usb-device-blacklist.rules && + /etc/udev/rules.d/77-pm3-usb-device-blacklist.rules &&\ udevadm control --reload-rules" add_bin_symlink pm3 ;; cyberchef) makedest - cd "${DESTDIR}" - src=$(python3 -c 'from urllib import request; import json; print(json.load(request.urlopen("https://api.github.com/repos/gchq/CyberChef/releases/latest"))["assets"][0]["browser_download_url"])') - download "${src}" "${DESTDIR}/cyberchef.zip" + cd "${DESTDIR}" || exit + download \ + "$(get_latest_github_release_url "gchq/CyberChef" ".*\\.zip")" \ + "${DESTDIR}/cyberchef.zip" unzip -d "${DESTDIR}" "${DESTDIR}/cyberchef.zip" ln -sf CyberChef*.html "${DESTDIR}/cyberchef.html" ;; @@ -270,8 +275,9 @@ case ${TOOL} in download \ https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool \ "${DESTDIR}/apktool" + jar_url=$(curl -s https://bitbucket.org/iBotPeaches/apktool/downloads/ | grep -o "/iBotPeaches/apktool/downloads/apktool_[0-9.]*.jar" | head -n 1) download \ - https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.3.3.jar \ + "https://bitbucket.org${jar_url}" \ "${DESTDIR}/apktool.jar" chmod +x "${DESTDIR}/apktool" add_bin_symlink apktool @@ -294,8 +300,14 @@ case ${TOOL} in PYTHON="${PYTHON}${PYVER}" "${PYTHON}" -m pip install --target "${PY_PACKAGES}" -Ur "${DESTDIR}/requirements.txt" "${PYTHON}" -m pip install --target "${PY_PACKAGES}" -U capstone unicorn - # capstone package is broken - cp "${PY_PACKAGES}/usr/lib/*/dist-packages/capstone/libcapstone.so" "${PY_PACKAGES}/capstone" + # capstone package is broken, find and copy the library manually + capstone_so_path=$(find "${PY_PACKAGES}/usr/lib" -name "libcapstone.so" -type f) + if [ -z "${capstone_so_path}" ]; then + die "Could not find libcapstone.so for pwndbg." + elif [ "$(echo "${capstone_so_path}" | wc -l)" -ne 1 ]; then + die "Found multiple libcapstone.so files for pwndbg, aborting." + fi + cp "${capstone_so_path}" "${PY_PACKAGES}/capstone/" ;; gef) makedest_or_die @@ -308,6 +320,7 @@ case ${TOOL} in "${DESTDIR}/gef.py" ;; aflplusplus) + deb_only install_pkgs libtool-bin libglib2.0-dev libpixman-1-dev clang clang-tools \ llvm python3-setuptools git clone "https://github.com/vanhauser-thc/AFLplusplus" "${DESTDIR}" @@ -328,22 +341,19 @@ case ${TOOL} in ;; cura) makedest - ver=$(python3 -c 'from urllib import request; import json; print(json.load(request.urlopen("https://api.github.com/repos/Ultimaker/Cura/releases/latest"))["name"].replace("v",""))') - echo "Latest Cura is ${ver}" download \ - "https://github.com/Ultimaker/Cura/releases/download/${ver}/Cura-${ver}.AppImage" \ + "$(get_latest_github_release_url "Ultimaker/Cura" ".*\\.AppImage")" \ "${DESTDIR}/Cura.AppImage" chmod +x "${DESTDIR}/Cura.AppImage" add_bin_symlink "Cura.AppImage" cura ;; rr) deb_only - ver=$(python3 -c 'from urllib import request; import json; print(json.load(request.urlopen("https://api.github.com/repos/mozilla/rr/releases/latest"))["name"])') - echo "Latest rr is ${ver}" + check_sudo download \ - "https://github.com/mozilla/rr/releases/download/${ver}/rr-${ver}-Linux-$(uname -m).deb" \ - "/tmp/rr.deb" - sudo dpkg -i /tmp/rr.deb + "$(get_latest_github_release_url "mozilla/rr" ".*-Linux-.*\\.deb")" \ + "${TMPDIR}/rr.deb" + sudo dpkg -i "${TMPDIR}/rr.deb" ;; nmap-parse-output) git clone --depth 1 \ @@ -359,38 +369,40 @@ fi EOF ;; logiops) + deb_only install_pkgs cmake libevdev-dev libudev-dev libconfig++-dev checkinstall git clone "https://github.com/PixlOne/logiops.git" "${DESTDIR}" mkdir -p "${DESTDIR}/build" - cd "${DESTDIR}/build" + cd "${DESTDIR}/build" || exit cmake .. make + check_sudo sudo checkinstall --pkgname logiops --maintainer "${USER}" -y ;; aws) - DN=$(mktemp -d) - cd "${DN}" + DN="${TMPDIR}/aws" + mkdir -p "${DN}" + cd "${DN}" || exit curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "${DN}/awscliv2.zip" unzip "${DN}/awscliv2.zip" mv "${DN}/aws/dist" "${DESTDIR}" add_bin_symlink aws - rm -rf ${DN} ;; tmpmail) install_pkgs curl w3m jq - mkdir -p ${DESTDIR} - curl -L "https://git.io/tmpmail" > ${DESTDIR}/tmpmail - chmod +x ${DESTDIR}/tmpmail + mkdir -p "${DESTDIR}" + download "https://git.io/tmpmail" "${DESTDIR}/tmpmail" + chmod +x "${DESTDIR}/tmpmail" add_bin_symlink tmpmail ;; gf) install_pkgs golang-go silversearcher-ag go install github.com/tomnomnom/gf@latest - mkdir -p ${HOME}/.config - if test -d ${HOME}/.config/gf ; then - git -C ${HOME}/.config/gf pull + mkdir -p "${HOME}/.config" + if test -d "${HOME}/.config/gf" ; then + git -C "${HOME}/.config/gf" pull else - git clone https://github.com/Matir/gf-patterns.git ${HOME}/.config/gf + git clone https://github.com/Matir/gf-patterns.git "${HOME}/.config/gf" fi ;; gron) @@ -410,9 +422,9 @@ EOF ;; cht.sh) install_pkgs rlwrap - mkdir -p ${DESTDIR} - curl https://cht.sh/:cht.sh > ${DESTDIR}/cht.sh - chmod +x ${DESTDIR}/cht.sh + mkdir -p "${DESTDIR}" + download "https://cht.sh/:cht.sh" "${DESTDIR}/cht.sh" + chmod +x "${DESTDIR}/cht.sh" add_bin_symlink cht.sh ;; age) @@ -420,9 +432,10 @@ EOF go install filippo.io/age/cmd/age-keygen@latest ;; docker-compose) - mkdir -p ${DESTDIR} + mkdir -p "${DESTDIR}" + latest_version=$(curl -s "https://api.github.com/repos/docker/compose/releases/latest" | jq -r '.tag_name') curl -L \ - "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" \ + "https://github.com/docker/compose/releases/download/${latest_version}/docker-compose-$(uname -s)-$(uname -m)" \ -o "${DESTDIR}/docker-compose" chmod +x "${DESTDIR}/docker-compose" add_bin_symlink docker-compose @@ -455,13 +468,13 @@ EOF echo "Must be able to run as sudo." exit 1 fi - dpkg_url=$(curl https://api.github.com/repos/dandavison/delta/releases/latest | \ - jq -r '.assets[] | select(.name|test(".*_amd64.deb")) | select(.name|test(".*musl.*")|not) | .browser_download_url') - dpkg_name="/tmp/delta_amd64.deb" + dpkg_url=$(get_latest_github_release_url "dandavison/delta" ".*_amd64.deb") + dpkg_name="${TMPDIR}/delta_amd64.deb" download "${dpkg_url}" "${dpkg_name}" sudo dpkg -i "${dpkg_name}" ;; ropper) + deb_only install_pkgs python3-z3 pip3 install --user pyvex ropper ;; @@ -478,41 +491,40 @@ EOF ln -sf "${DESTDIR}/completion/_kubens.zsh" "${COMPDIR}" ;; starship) - mkdir -p ${DESTDIR} + mkdir -p "${DESTDIR}" download \ "https://github.com/starship/starship/releases/latest/download/starship-$(uname -m)-unknown-linux-musl.tar.gz" \ - /tmp/starship.tar.gz - tar -C ${DESTDIR} -zxf /tmp/starship.tar.gz starship + "${TMPDIR}/starship.tar.gz" + tar -C "${DESTDIR}" -zxf "${TMPDIR}/starship.tar.gz" starship add_bin_symlink starship ;; arduino-cli) mkdir -p "${DESTDIR}" download \ "https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_64bit.tar.gz" \ - /tmp/arduino-cli.tar.gz - tar -C "${DESTDIR}" -zxf /tmp/arduino-cli.tar.gz arduino-cli + "${TMPDIR}/arduino-cli.tar.gz" + tar -C "${DESTDIR}" -zxf "${TMPDIR}/arduino-cli.tar.gz" arduino-cli add_bin_symlink arduino-cli ;; ghidra) - zip_url=$(curl https://api.github.com/repos/NationalSecurityAgency/ghidra/releases/latest | \ - jq -r '.assets[] | select(.name|test(".*.zip")) | .browser_download_url') - download "${zip_url}" /tmp/ghidra.zip - unzip -d "${DESTDIR}" /tmp/ghidra.zip - mv ${DESTDIR}/*/* ${DESTDIR} + zip_url=$(get_latest_github_release_url "NationalSecurityAgency/ghidra" ".*\\.zip") + download "${zip_url}" "${TMPDIR}/ghidra.zip" + unzip -d "${DESTDIR}" "${TMPDIR}/ghidra.zip" + mv "${DESTDIR}"/*/* "${DESTDIR}" add_bin_symlink ghidraRun ghidra ;; doctl) # TODO: other architectures - tar_url=$(curl https://api.github.com/repos/digitalocean/doctl/releases/latest | \ - jq -r '.assets[] | select(.name|test(".*linux-amd64\\.tar\\.gz")) | .browser_download_url') - download "${tar_url}" /tmp/doctl.tar.gz + tar_url=$(get_latest_github_release_url "digitalocean/doctl" ".*linux-amd64\\.tar\\.gz") + download "${tar_url}" "${TMPDIR}/doctl.tar.gz" mkdir -p "${DESTDIR}" - tar -C "${DESTDIR}" -zxf /tmp/doctl.tar.gz "doctl" + tar -C "${DESTDIR}" -zxf "${TMPDIR}/doctl.tar.gz" "doctl" add_bin_symlink doctl ;; rustup) - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ - sh -s -- --no-modify-path -y + rustup_init="${TMPDIR}/rustup-init.sh" + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o "${rustup_init}" + sh "${rustup_init}" --no-modify-path -y ;; igrep) if ! command -v cargo >/dev/null 2>&1 ; then diff --git a/bin/nvidia_hold.sh b/bin/nvidia_hold.sh index 6866dec..0f10f22 100755 --- a/bin/nvidia_hold.sh +++ b/bin/nvidia_hold.sh @@ -5,7 +5,7 @@ function list_nvidia_installed { } function hold_or_unhold { - apt-mark "${1:-hold}" $(list_nvidia_installed) + list_nvidia_installed | xargs apt-mark "${1:-hold}" } case "$1" in diff --git a/bin/pactl_helper b/bin/pactl_helper index 2aa3433..d8e6810 100755 --- a/bin/pactl_helper +++ b/bin/pactl_helper @@ -37,7 +37,7 @@ function volume { case "$1" in mute|micmute|volume) - $* + "$@" ;; *) echo "Unknown command!" diff --git a/bin/qdisc_span.sh b/bin/qdisc_span.sh index 8b29290..546e59d 100755 --- a/bin/qdisc_span.sh +++ b/bin/qdisc_span.sh @@ -43,6 +43,6 @@ function get_bridge_ifaces { bridge link | grep "master ${1}" | cut -d: -f2 | cut -d@ -f1 } -for iface in $(get_bridge_ifaces "${BRIDGE}") ; do +get_bridge_ifaces "${BRIDGE}" | while IFS= read -r iface ; do handle_iface "$iface" done diff --git a/bin/screenshot.sh b/bin/screenshot.sh index b580cb7..1c4df8c 100755 --- a/bin/screenshot.sh +++ b/bin/screenshot.sh @@ -25,14 +25,6 @@ function flameshot_gui_capture { flameshot gui -p "${SCREENDIR}" } -function flameshot_region_capture { - flameshot_gui_capture -} - -function flameshot_window_capture { - flameshot_gui_capture -} - function flameshot_full_capture { flameshot full -p "${SCREENDIR}" } @@ -52,7 +44,35 @@ function scrot_full_capture { case "${CMD}" in region|window|full) mkdir -p "${SCREENDIR}" - ${TOOL}_${CMD}_capture + case "${TOOL}" in + flameshot) + case "${CMD}" in + region|window) + flameshot_gui_capture + ;; + full) + flameshot_full_capture + ;; + esac + ;; + scrot) + case "${CMD}" in + region) + scrot_region_capture + ;; + window) + scrot_window_capture + ;; + full) + scrot_full_capture + ;; + esac + ;; + *) + echo "Error: Unknown or unsupported tool '${TOOL}'" >&2 + exit 1 + ;; + esac exit $? ;; *) diff --git a/bin/switch_virt.sh b/bin/switch_virt.sh index 6cb259c..40368f2 100755 --- a/bin/switch_virt.sh +++ b/bin/switch_virt.sh @@ -7,7 +7,7 @@ fi if [ `whoami` != "root" ] ; then if which sudo >/dev/null 2>&1 ; then - sudo $0 $* + sudo "$0" "$@" exit fi echo "Sorry, this requires root." >&2