commit 9af87d9ae9e2a0d293b88e25c984bad57788bce1 Author: JeremyStarTM Date: Fri Mar 15 01:32:32 2024 +0100 Initial commit diff --git a/bin/updatechecker b/bin/updatechecker new file mode 100755 index 0000000..6021b31 --- /dev/null +++ b/bin/updatechecker @@ -0,0 +1,32 @@ +#!/bin/bash +cd "/etc/sysdotfiles" +export "COLOR=31" +export "COLOR_REGULAR=\e[0;${COLOR}m" +export "COLOR_BOLD=\e[1;${COLOR}m" +export "COLOR_RESET=\e[0m" +export "COMMIT=$(env PAGER= git log -n 1 --pretty=format:\"%H\")" +export "LATEST_COMMIT=$(curl -sX 'GET' 'https://git.staropensource.de/api/v1/repos/JeremyStarTM/syspunktdateien/branches/develop' -H 'accept: application/json'|jq --monochrome-output '.commit.id')" +export "LATEST_COMMIT_MESSAGE=$(curl -sX 'GET' 'https://git.staropensource.de/api/v1/repos/JeremyStarTM/syspunktdateien/branches/develop' -H 'accept: application/json'|jq --monochrome-output '.commit.message'|sed 's/\\n//g')" + +if [ "$COMMIT" == "$LATEST_COMMIT" ] || [ -z "$LATEST_COMMIT" ]; then + export "UPDATE=false" +else + export "UPDATE=true" +fi + +if [ ! "$SCRIPTED" == "true" ]; then + if [ "$UPDATE" == "true" ]; then + echo -e "${COLOR_BOLD}An update for jstm's syspunktdateien is available." + echo -e "${COLOR_REGULAR}Latest commit: ${LATEST_COMMIT}" + echo " -> Message: ${LATEST_COMMIT_MESSAGE}" + echo "" + echo -e "${COLOR_BOLD}Update by executing \"sysdotfiles-updater\"" + echo -en "${COLOR_RESET}" + elif [ ! "${BASHRC}" == "true" ]; then + echo -e "${COLOR_BOLD}No update available" + fi +else + if [ "$UPDATE" == "true" ]; then + echo "$LATEST_COMMIT_MESSAGE" + fi +fi diff --git a/bin/updater b/bin/updater new file mode 100755 index 0000000..f0c0104 --- /dev/null +++ b/bin/updater @@ -0,0 +1,26 @@ +#!/bin/bash +export "UPDATER_VERSION=1" +if [ "$STAGE" == "1" ]; then + echo ":: Removing files (again)" + ./uninstall.sh + echo ":: Installing files" + ./install.sh + echo ":: Update complete." + rm -rf "/etc/.jstm_sysdotfiles_updater" +else + echo ":: Checking for updates" + if [ ! "$1" == "--force" ] && [ "$(env SCRIPTED=true sysdotfiles-updatechecker)" == "" ]; then + echo ":: No update is available. Use \"--force\" to update anyway." + exit 1 + fi + # Unused as of now, may be used in a later commit + echo ":: Writing info file" + echo "UPDATER_VERSION_OLD=${UPDATER_VERSION}" > "/etc/.jstm_sysdotfiles_updater" + echo ":: Removing files" + cd "/etc/sysdotfiles" + ./uninstall.sh + echo ":: Pulling updates" + git pull + echo ":: Running updater (stage 2)" + env STAGE=1 "/etc/sysdotfiles/bin/updater" +fi diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..cc44454 --- /dev/null +++ b/install.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# jeremystartm's sysdotfiles "installer" + +if [ ! -f "/etc/.jstm_sysdotfiles" ]; then + echo ":: Removing files" + ./uninstall.sh &> /dev/null +fi + +# useful function +function link() { + if [ -a "/${2}" ]; then + [[ -n "$VERBOSE_WARNING" ]] && echo ":: Warning: ${2} already exists." + else + echo ":: Linking ${2}" + ln -s "$(pwd)/${1}" "/${2}" + fi +} + +# update/clone repositories +if [ ! -d "jstmbash" ]; then + git clone "https://git.staropensource.de/JeremyStarTM/jstmbash.git" jstmbash +else + cd jstmbash + git pull + cd .. +fi + +# create directories +#mkdir -p "/unused/" + +# bash configuration +link "jstmbash" "etc/jstmbash" +link "lone-files/jstmbash.config.env" "etc/jstmbash.env" +link "lone-files/bashrc" "etc/bash.bashrc" + +# makepkg +link "lone-files/makepkg.conf" "etc/makepkg.conf" + +# punktdateien scripts +link "bin/updatechecker" "usr/local/bin/sysdotfiles-updatechecker" +link "bin/updater" "usr/local/bin/sysdotfiles-updater" + +# write install file +echo "pls don't remove" > "/etc/.jstm_sysdotfiles" diff --git a/lone-files/bashrc b/lone-files/bashrc new file mode 100755 index 0000000..d8248e9 --- /dev/null +++ b/lone-files/bashrc @@ -0,0 +1,25 @@ +# +# /etc/bash.bashrc +# + +# If not running interactively, don't do anything +[[ $- != *i* ]] && return + +[[ $DISPLAY ]] && shopt -s checkwinsize + +PS1='[\u@\h \W]\$ ' + +case ${TERM} in + Eterm*|alacritty*|aterm*|foot*|gnome*|konsole*|kterm*|putty*|rxvt*|tmux*|xterm*) + PROMPT_COMMAND+=('printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"') + + ;; + screen*) + PROMPT_COMMAND+=('printf "\033_%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"') + ;; +esac + +if [[ -r /usr/share/bash-completion/bash_completion ]]; then + . /usr/share/bash-completion/bash_completion +fi +source /etc/jstmbash/init.source diff --git a/lone-files/jstmbash.config.env b/lone-files/jstmbash.config.env new file mode 100755 index 0000000..0aaee56 --- /dev/null +++ b/lone-files/jstmbash.config.env @@ -0,0 +1,199 @@ +#!/bin/bash +# shellcheck disable=SC2034 +# configuration for jeremystartm's bashrc + +# DO NOT CHANGE THIS +JSTMBASH_VERSION=1 +# DO NOT CHANGE THIS + +# GLOBAL +## FLOW_CONTROL +### Type: bool +### Default value: false +### Enables or disables flow control. +### https://en.wikipedia.org/wiki/Flow_control_(data) +JSTMBASH_GLOBAL_FLOW_CONTROL=false +## PROMPT +### Type: string +### Default value: "\[\033[38;5;33m\][\[$(tput sgr0)\]\[\033[38;5;38m\]\u\[$(tput sgr0)\]\[\033[38;5;33m\]@\[$(tput sgr0)\]\[\033[38;5;38m\]\H\[$(tput sgr0)\]\[\033[38;5;33m\]:\[$(tput sgr0)\]\[\033[38;5;38m\]\W\[$(tput sgr0)\] \[$(tput sgr0)\]\[\033[38;5;214m\]\$?\[$(tput sgr0)\]\[\033[38;5;33m\]]\\$\[$(tput sgr0)\] " +### Your $PS1, better known as prompt. +### Nice generator: https://ezprompt.net +JSTMBASH_GLOBAL_PROMPT="\[\033[38;5;33m\][\[$(tput sgr0)\]\[\033[38;5;38m\]\u\[$(tput sgr0)\]\[\033[38;5;33m\]@\[$(tput sgr0)\]\[\033[38;5;38m\]\H\[$(tput sgr0)\]\[\033[38;5;33m\]:\[$(tput sgr0)\]\[\033[38;5;38m\]\W\[$(tput sgr0)\] \[$(tput sgr0)\]\[\033[38;5;214m\]\$?\[$(tput sgr0)\]\[\033[38;5;33m\]]\\$\[$(tput sgr0)\] " +## PROMPT_COMMAND +### Type: string +### Default value: "" +### Place commands you want to invoke before +### displaying your PS1, useful for multiline +### prompts. Better known as $PROMPT_COMMAND +JSTMBASH_GLOBAL_PROMPT_COMMAND="history -a" +## PROMPT_INCOMPLETE +### Type: bool +### Default value: true +### Replaces the $PS2 aka. "the incomplete command prompt" with something fancy. +JSTMBASH_GLOBAL_PROMPT_INCOMPLETE=true +## EDITOR +### Type: string +### Default value: nano +### Defines the $EDITOR variable +JSTMBASH_GLOBAL_EDITOR="nano" +## THREADS +### Type: integer +### Default value: "$(nproc)" +### The default number of threads +JSTMBASH_GLOBAL_THREADS="$(nproc)" + +# WARNINGS +## NO_TRUECOLOR +### Type: bool +### Default value: true +### Warns if the terminal (emulator) does not have truecolor support. +### Disable if your terminal emulator DOES support 16 million colors. +JSTMBASH_WARNINGS_NO_TRUECOLOR=false +## EXA_UNMAINTAINED +### Type: bool +### Default value: true +### Warns about exa still being installed and recommends eza instead. +### Disable if you for some reason still require exa. +JSTMBASH_WARNINGS_EXA_UNMAINTAINED=true + +# PATH +## ENFORCE_CLEAN +### Type: bool +### Default value: true +### Overrides the PATH variable and includes +### entries for flatpak, cargo, etc.. +JSTMBASH_PATH_ENFORCE_CLEAN=true +## APPENDS +### Type: string +### Default value: "" +### Appends directories to the PATH variable. +### Add them like this: "/path/to/bin:/path/to/goodies:/path/to/shit" +JSTMBASH_PATH_APPENDS="/opt/cmds" + +# GOODIES +## EXTRACT +### Type: bool +### Default value: true +### Type "extract /path/to/archive" and it will autodetect +### the required extraction program. +JSTMBASH_GOODIES_EXTRACT=true + +# ALIASES +## PKGMGR_REPLACE +### Type: bool +### Default value: false +### Set to true if you want to replace your package +### manager with another one/an frontend for it. +JSTMBASH_ALIASES_PKGMGR_REPLACE=true +## PKGMGR_REPLACE_FROM +### Type: string +### Default value: "" +### The package manager command you want to replace. +JSTMBASH_ALIASES_PKGMGR_REPLACE_FROM="pacman" +## PKGMGR_REPLACE_TO +### Type: string +### Default value: "" +### The package manager command you want to use instead. +JSTMBASH_ALIASES_PKGMGR_REPLACE_TO="paru" +## USE_EZA +### Type: bool +### Default value: true +### Replaces ls and dir with eza +JSTMBASH_ALIASES_USE_EZA=true +## USE_BAT +### Type: bool +### Default value: true +### Replaces cat with bat +JSTMBASH_ALIASES_USE_BAT=true +## USE_MOAR +### Type: bool +### Default value: true +### Replaces less and more with moar +JSTMBASH_ALIASES_USE_MOAR=true + +# FANCIER +## EZA +### Type: bool +### Default value: true +### Makes eza fancier. +JSTMBASH_FANCIER_EZA=true +## EZA_LONG +### Type: bool +### Default value: false +### Enables the -l flag +JSTMBASH_FANCIER_EZA_LONG=true +## EZA_DIRECTORIES_BEFORE_FILES +### Type: bool +### Default value: true +### Lists directories before files +### Only applies to long mode +JSTMBASH_FANCIER_EZA_DIRECTORIES_BEFORE_FILES=true +## EZA_SIZE1000 +### Type: bool +### Default value: false +### Displays in KB, MB, GB if true and in KiB, MiB, GiB if false +### Only applies to long mode +JSTMBASH_FANCIER_EZA_SIZE1000=false +## EZA_DISPLAYMOUNTS +### Type: bool +### Default value: false +### Displays mountpoint information +### Only applies to long mode +JSTMBASH_FANCIER_EZA_DISPLAY_MOUNTS=true +## EZA_OCTAL_PERMISSIONS +### Type: bool +### Default value: false +### Displays permissions with numbers +### Example: ".rwxr--r--" -> "0744" +### Only applies to long mode +JSTMBASH_FANCIER_EZA_OCTAL_PERMISSIONS=false +## EZA_GITINFO +### Type: bool +### Default value: true +### Displays the git status for each file and directory +### Only applies to long mode +JSTMBASH_FANCIER_EZA_GITINFO=false +## BAT +### Type: bool +### Default value: true +### Makes bat fancier. +JSTMBASH_FANCIER_BAT=true +## BAT_USE_PAGER +### Type: bool +### Default value: true +### Should bat use a pager? +JSTM_FANCIER_BAT_USE_PAGER=false +## MOAR +### Type: bool +### Default value: true +### Makes moar fancier. +JSTMBASH_FANCIER_MOAR=true +## MOAR_STYLE +### Type: string +### Default value: "dracula" +### What theme/style moar should use. +JSTMBASH_FANCIER_MOAR_STYLE="dracula" +## YTFZF +### Type: bool +### Default value: true +### Makes ytfzf fancier. +JSTMBASH_FANCIER_YTFZF=true +## YTFZF_THUMBVIEWER +### Type: string +### Default value: "catimg" +### Which thumbnail viewer program ytfzf should use. +### Available are: chafa, catimg, imv, mpv, swayimg and swayimg-hyprland +JSTMBASH_FANCIER_YTFZF_THUMBVIEWER="swayimg-hyprland" +## YTFZF_ALLOW_NSFW +### Type: bool +### Default value: false +### If ytfzf should 18+ content (only works for odysee/lbry). +### We will bonk you if this is true! +JSTMBASH_FANCIER_YTFZF_NSFW=false +## YTFZF_REQUIRE_SUBTITLES +### Type: bool +### Default value: false +### Only show videos with subtitles. +JSTMBASH_FANCIER_YTFZF_SUBTITLES=false + +# EOF <- Yes, you've reached the end. diff --git a/lone-files/makepkg.conf b/lone-files/makepkg.conf new file mode 100644 index 0000000..d4b2f1b --- /dev/null +++ b/lone-files/makepkg.conf @@ -0,0 +1,275 @@ +#!/hint/bash +# shellcheck disable=2034 + +# Configuration +## Packager +## Leave both empty to disable, leave $_packager_email empty to disable +_packager="JeremyStarTM" +_packager_email="jeremystartm@staropensource.de" + +## GPG Key +## Leave empty to disable +_gpgkey="" + +## March +## to get a list of all march values by executing "gcc --target-help" and search for -march= +_march="znver3" + +## Mtune +## to get a list of all mtune values by executing "gcc --target-help" and search for -mtune= +_mtune="znver3" + +## CPU flags +## Define your cpu flags here (get values by installing cpuid2cpuflags from the AUR and running "cpuid2cpuflags") +_cpuflags="aes avx avx2 f16c fma3 mmx mmxext pclmul popcnt rdrand sha sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3 vpclmulqdq" + +## Streaming SIMD +### SSE1 and SSE2 are default on amd64, use "cat /proc/cpuinfo" to get info for all others +### Different cpuflags names: sse3=pni mmx=mmxext +_sse1="true" +_sse2="true" +_sse3="true" +_sse4="true" +_sse4dot1="true" +_sse4dot2="true" +_sse4a="true" +_mmx="true" +_3dnow="false" + +## Safe CFLAGS -> see https://wiki.gentoo.org/wiki/Safe_CFLAGS +_safecflags="" + +## Compilation caches +_ccache="false" +_sccache="false" + +## Replacements +_mold="true" + +## Elevation command +## Must be an array +_pacman_elevationcommand="(sudo)" + + +########################################## +## Modify things below for more control ## +########################################## + + +# Architecture and host triple +CARCH="x86_64" +CHOST="x86_64-pc-linux-gnu" + + +# Downloaders +DLAGENTS=('file::/usr/bin/curl -qgC - -o %o %u' + 'ftp::/usr/bin/curl -qgfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u' + 'http::/usr/bin/curl -qgb "" -fLC - --retry 3 --retry-delay 3 -o %o %u' + 'https::/usr/bin/curl -qgb "" -fLC - --retry 3 --retry-delay 3 -o %o %u' + 'rsync::/usr/bin/rsync --no-motd -z %u %o' + 'scp::/usr/bin/scp -C %u %o') + + +# Source control +VCSCLIENTS=('bzr::breezy' + 'fossil::fossil' + 'git::git' + 'hg::mercurial' + 'svn::subversion') + + +# Tool flags +## GCC (C) +CPU_FLAGS_X86="${_cpuflags}" +CFLAGS="-march=${_march} -mtune=${_mtune} -O2 -ftree-vectorize -pipe -fomit-frame-pointer -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection" + +## Streaming SIMD +if [ "${_sse1}" == "true" ]; then + export "CFLAGS=${CFLAGS} -msse" +fi +if [ "${_sse2}" == "true" ]; then + export "CFLAGS=${CFLAGS} -msse2" +fi +if [ "${_sse3}" == "true" ]; then + export "CFLAGS=${CFLAGS} -msse3" +fi +if [ "${_sse4}" == "true" ]; then + export "CFLAGS=${CFLAGS} -msse4" +fi +if [ "${_sse4dot1}" == "true" ]; then + export "CFLAGS=${CFLAGS} -msse4.1" +fi +if [ "${_sse4dot2}" == "true" ]; then + export "CFLAGS=${CFLAGS} -msse4.2" +fi +if [ "${_sse4a}" == "true" ]; then + export "CFLAGS=${CFLAGS} -msse4a" +fi +if [ "${_mmx}" == "true" ]; then + export "CFLAGS=${CFLAGS} -mmmx" +fi +if [ "${_3dnow}" == "true" ]; then + export "CFLAGS=${CFLAGS} -m3dnow" +fi +if [ -n "${_safecflags}" ]; then + export "CFLAGS=${CFLAGS} ${_safecflags}" +fi + +## GCC (C++) +CXXFLAGS="${CFLAGS} -Wp,-D_GLIBCXX_ASSERTIONS" +CPPFLAGS="${CXXFLAGS}" + +## LD +LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now" +if [ "${_mold}" == "true" ]; then + export "LDFLAGS=${LDFLAGS},-fuse-ld=mold" +fi +LTOFLAGS="-flto=auto" + +## Rust +RUSTFLAGS="-C target-cpu=native" +if [ "${_mold}" == "true" ]; then + export "RUSTFLAGS=${RUSTFLAGS} -C link-arg=-fuse-ld=mold" +fi + +## Make +MAKEFLAGS="-j$(nproc)" + +## Debug flags +### GCC (C) +DEBUG_CFLAGS="-g" + +### GCC (C++) +DEBUG_CXXFLAGS="$DEBUG_CFLAGS" +DEBUG_CPPFLAGS="${DEBUG_CXXFLAGS}" + +### Rust +DEBUG_RUSTFLAGS="-C debuginfo=2" + + +# Makepkg settings +## Build environment +## Default: BUILDENV=(!distcc !color !ccache check !sign) +## Executes: +## -> distcc: Use the Distributed C/C++/ObjC compiler +## -> color: Colorize output messages +## -> ccache: Use ccache to cache compilation +## -> check: Run the check() function if present in the PKGBUILD +## -> sign: Generate PGP signature file +BUILDENV="!distcc color" +if [ "${_ccache}" == "true" ]; then + export "BUILDENV=${BUILDENV} ccache" +else + export "BUILDENV=${BUILDENV} !ccache" +fi +export BUILDENV="${BUILDENV} check" +if [ -n "${_gpgkey}" ]; then + export "BUILDENV=${BUILDENV} sign" +else + export "BUILDENV=${BUILDENV} !sign" +fi +export BUILDENV=(${BUILDENV}) + +## Build directory +## Default: BUILDDIR= +BUILDDIR=/tmp/makepkg + +## Global package options +## Default: OPTIONS=(!strip docs libtool staticlibs emptydirs !zipman !purge !debug !lto) +## Executes: +## -> strip: Strip symbols from binaries/libraries +## -> docs: Save doc directories specified by DOC_DIRS +## -> libtool: Leave libtool (.la) files in packages +## -> staticlibs: Leave static library (.a) files in packages +## -> emptydirs: Leave empty directories in packages +## -> zipman: Compress manual (man and info) pages in MAN_DIRS with gzip +## -> purge: Remove files specified by PURGE_TARGETS +## -> debug: Add debugging flags as specified in DEBUG_* variables +## -> lto: Add compile flags for building with link time optimization +OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge debug lto) + +## File integrity checks to use +## Default: INTEGRITY_CHECK=(sha256) +## Valid: md5, sha1, sha224, sha256, sha384, sha512, b2 +INTEGRITY_CHECK=(sha256) + +## Options for stripping binaries (see "man strip") +## Default: STRIP_BINARIES="--strip-all" +STRIP_BINARIES="--strip-all" + +## Options for stripping shared libraries (see "man strip") +## Default: STRIP_SHARED="--strip-unneeded" +STRIP_SHARED="--strip-unneeded" + +## Options for stripping static librarie (see "man strip") +STRIP_STATIC="--strip-debug" + +## Manual directories (man & info) to compress +## Default: MAN_DIRS=({usr{,/local}{,/share},opt/*}/{man,info}) +MAN_DIRS=({usr{,/local}{,/share},opt/*}/{man,info}) + +## Documentation directories to remove +## Default: DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc}) +DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc}) + +## Files to remove from all packages +## Default: PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod) +PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod) + +## Directories to store source code in (debug packages) +## Default: DBGSRCDIR="/usr/src/debug" +DBGSRCDIR="/usr/src/debug" + + +# Package output +## Where all packages will be placed +## Default: PKGDEST= + +## Where source files will be cached +## Default: SRCDEST= + +## Where source packages will be placed +## Default: SRCPKGDEST= + +## Where log files will be placed +## Default: LOGDEST= + +## Packager +## Default: +if [ -n "${_packager}" ] && [ -n "${_packager_email}" ]; then + export PACKAGER="${_packager} <${_packager_email}>" +elif [ -n "${_packager}" ] && [ -z "${_packager_email}" ]; then + export PACKAGER="${_packager}" +else + export PACKAGER="" +fi + +## GPG Key +## Default: +if [ -n "${_gpgkey}" ]; then + export GPGKEY="${_gpgkey}" +else + export GPGKEY="" +fi + +## Compression commands +COMPRESSGZ=(gzip -c -f -n) +COMPRESSBZ2=(bzip2 -c -f) +COMPRESSXZ=(xz -c -z -) +COMPRESSZST=(zstd -c -T0 --ultra -20 -) +COMPRESSLRZ=(lrzip -q) +COMPRESSLZO=(lzop -q) +COMPRESSZ=(compress -c -f) +COMPRESSLZ4=(lz4 -q) +COMPRESSLZ=(lzip -c -f) + +## Extension defaults +PKGEXT='.pkg.tar.zst' +SRCEXT='.src.tar.gz' + + +# Other +## Default: PACMAN_AUTH= +PACMAN_AUTH=${_pacman_elevationcommand} + +# vim: set ft=sh ts=2 sw=2 et: diff --git a/uninstall.sh b/uninstall.sh new file mode 100755 index 0000000..0828eb9 --- /dev/null +++ b/uninstall.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# jeremystartm's sysdotfiles "installer" + +# useful function +function unlink() { + if [ -a "/${1}" ]; then + echo ":: Unlinking ${1}" + rm -rf "/${1}" + fi +} + +# repositories +[[ -n "$REMOVE_REPOSITORIES" ]] && rm -rf "jstmbash" + +# install bit +[[ -n "$REMOVE_INSTALLBIT" ]] && rm -rf "/etc/.jstm_dotfiles" + +# bash configuration +unlink "etc/jstmbash" +unlink "etc/jstmbash.env" +unlink "etc/bash.bashrc" + +# makepkg +unlink "etc/makepkg.conf" + +# punktdateien scripts +unlink "usr/local/bin/sysdotfiles-updatechecker" +unlink "usr/local/bin/sysdotfiles-updater" + +# write install file +echo "pls don't remove" > "/etc/.jstm_sysdotfiles"