deicidus
2 years ago
44 changed files with 2024 additions and 4 deletions
@ -0,0 +1,24 @@
|
||||
#!/bin/sh |
||||
|
||||
install_cd() { |
||||
if ! grep -q "alias cd=" ~/.bashrc; then |
||||
echo "Do you wish to memorize this spell, so that you look around rooms automatically as you use 'cd'? (yes/no)" |
||||
read -r answer |
||||
if [ "$answer" = "yes" ]; then |
||||
scriptpath="$(dirname $(readlink -f $0))" |
||||
filename="$(basename "$0")" |
||||
echo "alias cd=\". $scriptpath/$filename\"" >> ~/.bashrc |
||||
echo "Spell memorized in .bashrc, so the mud will always be active in the terminal." |
||||
else |
||||
echo "The mud will only run in this shell window." |
||||
fi |
||||
fi |
||||
} |
||||
|
||||
install_cd |
||||
|
||||
# Call the standard cd command |
||||
builtin cd "$@" |
||||
|
||||
# Look around the room |
||||
look |
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env sh |
||||
|
||||
# This magical spell reveals the dimensions of the terminal window, displaying the width and height as if by magic. |
||||
|
||||
# Define the function to calculate the dimensions of the terminal window |
||||
fathom_dimensions() { |
||||
# Get the width of the terminal window |
||||
width=$(tput cols) |
||||
|
||||
# Get the height of the terminal window |
||||
height=$(tput lines) |
||||
|
||||
# Output the dimensions of the terminal window |
||||
echo "Width: $width" |
||||
echo "Height: $height" |
||||
} |
||||
|
||||
# Check if the script is being called from another script |
||||
if [ "${BASH_SOURCE[0]}" = "$0" ]; then |
||||
# If not, call the function |
||||
fathom_dimensions |
||||
fi |
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env sh |
||||
|
||||
# This magical spell reveals the dimensions of the terminal window, displaying the width and height as if by magic. |
||||
|
||||
# Define the function to calculate the dimensions of the terminal window |
||||
fathom_height() { |
||||
# Get the width of the terminal window |
||||
width=$(tput rows) |
||||
|
||||
# Output the dimensions of the terminal window |
||||
echo "height" |
||||
} |
||||
|
||||
# Check if the script is being called from another script |
||||
if [ "${BASH_SOURCE[0]}" = "$0" ]; then |
||||
# If not, call the function |
||||
fathom_dimensions |
||||
fi |
@ -0,0 +1,59 @@
|
||||
#!/bin/sh |
||||
|
||||
# This script serves as a magic scroll that conjures a systemd service |
||||
# from a given template and a set of variable-value pairs |
||||
|
||||
if [ $# -lt 1 ]; then |
||||
echo "Usage: $0 /path/to/service/template key=value [key=value...]" |
||||
exit 1 |
||||
fi |
||||
|
||||
# Ensure systemd is available |
||||
if ! command -v systemctl >/dev/null 2>&1; then |
||||
echo "Systemd is not installed or not in PATH. Exiting." |
||||
exit 1 |
||||
fi |
||||
|
||||
service_dir=/etc/systemd/system |
||||
template_path=$1 |
||||
service_file=$(basename "$template_path") |
||||
service_path="$service_dir/$service_file" |
||||
|
||||
# Ask for confirmation before overwriting an existing file |
||||
if [ -f "$service_path" ]; then |
||||
if ask_yn "Service file $service_path already exists. Overwrite?" "N"; then |
||||
echo "User chose not to overwrite. Exiting." |
||||
exit 1 |
||||
fi |
||||
fi |
||||
|
||||
# Prepare a sed command based on the remaining arguments |
||||
shift |
||||
substitution_cmd="" |
||||
for arg in "$@"; do |
||||
substitution_cmd="${substitution_cmd}s|\\\$${arg%%=*}|${arg#*=}|g;" |
||||
done |
||||
|
||||
# Perform substitutions |
||||
sudo sh -c "sed \"$substitution_cmd\" \"$template_path\" > \"$service_path\"" |
||||
|
||||
# Ask for missing variables |
||||
while IFS= read -r line; do |
||||
if echo "$line" | grep -q '\$'; then |
||||
var=$(echo "$line" | sed -n -e 's/^.*\$\([A-Z_]*\).*$/\1/p') |
||||
if [ -n "$var" ]; then |
||||
echo "Enter a value for $var: " |
||||
read -r value |
||||
sed -i "s|\$$var|$value|g" "$service_path" |
||||
fi |
||||
fi |
||||
done < "$service_path" |
||||
|
||||
# Set permissions |
||||
sudo chmod 644 "$service_path" |
||||
|
||||
# Reload systemd |
||||
systemctl daemon-reload |
||||
|
||||
echo "Service installed at $service_path" |
||||
exit 0 |
@ -0,0 +1,38 @@
|
||||
#!/bin/sh |
||||
|
||||
# This script serves as a scrying spell, checking if a given systemd service is installed |
||||
|
||||
if [ $# -lt 1 ]; then |
||||
echo "Usage: $0 service_name" |
||||
exit 1 |
||||
fi |
||||
|
||||
# Ensure systemd is available |
||||
if ! command -v systemctl >/dev/null 2>&1; then |
||||
echo "Systemd is not installed or not in PATH. Exiting." |
||||
exit 1 |
||||
fi |
||||
|
||||
service_dir=/etc/systemd/system |
||||
service_name=$1 |
||||
|
||||
# Add .service if not present in the name |
||||
case $service_name in |
||||
*.service) ;; |
||||
*) service_name="$service_name.service" ;; |
||||
esac |
||||
|
||||
service_path="$service_dir/$service_name" |
||||
|
||||
# Check if service file exists |
||||
if [ -f "$service_path" ]; then |
||||
if [ -t 1 ]; then # Check if output is a terminal |
||||
echo "$service_name is installed." |
||||
fi |
||||
exit 0 # Service is installed (success) |
||||
else |
||||
if [ -t 1 ]; then # Check if output is a terminal |
||||
echo "$service_name is not installed." |
||||
fi |
||||
exit 1 # Service is not installed (failure) |
||||
fi |
@ -0,0 +1,44 @@
|
||||
#!/bin/sh |
||||
|
||||
# This script is a magical tome of sorcery, commanding the elusive entity known as Bitcoin. |
||||
|
||||
. colors |
||||
|
||||
# Displays the menu |
||||
display_menu() { |
||||
title="${BOLD}${CYAN}Bitcoin: $(bitcoin-status)" |
||||
blockchain_info="Display Blockchain Info%bitcoin-cli getblockchaininfo" |
||||
set_config="Configure Bitcoin%configure-bitcoin" |
||||
change_directory="Change Bitcoin Directory%change-bitcoin-directory" |
||||
clear_cache="Clear Bitcoin Cache%# coming soon" |
||||
repair_permissions="Repair Permissions%repair-bitcoin-permissions # Sometimes necessary" |
||||
exit_option="Exit%kill -2 $$" # Commands are run with 'eval' by the menu script, so we can't simply say 'exit'. The keyword $$ gets this scripts PID and the -2 code is SIGINT aka Ctrl-C |
||||
|
||||
if is-bitcoin-installed; then |
||||
install_bitcoin_option="Uninstall Bitcoin%uninstall-bitcoin" |
||||
if is-service-installed bitcoin; then |
||||
install_service_option="Uninstall Bitcoin Service%remove-service bitcoin" |
||||
if is-bitcoin-running; then |
||||
bitcoin_server_option="Stop Bitcoin Service%sudo systemctl stop bitcoind" |
||||
menu "$title" "$blockchain_info" "$set_config" "$change_directory" "$clear_cache" "$repair_permissions" "$bitcoin_server_option" "$install_service_option" "$install_bitcoin_option" "$exit_option" |
||||
else |
||||
bitcoin_server_option="Start Bitcoin Service%sudo systemctl start bitcoind" |
||||
menu "$title" "$set_config" "$change_directory" "$clear_cache" "$repair_permissions" "$bitcoin_server_option" "$install_service_option" "$install_bitcoin_option" "$exit_option" |
||||
fi |
||||
else |
||||
install_service_option="Install Bitcoin Service%install-service-template ./bitcoin.service \"BITCOIND=`which bitcoind`\"" |
||||
menu "$title" "$set_config" "$change_directory" "$clear_cache" "$repair_permissions" "$install_service_option" "$install_bitcoin_option" "$exit_option" |
||||
fi |
||||
else |
||||
install_bitcoin_option="Install Bitcoin%install-bitcoin" |
||||
menu "$title" "$install_bitcoin_option" "$exit_option" |
||||
fi |
||||
} |
||||
|
||||
# Catch Ctrl-C and exit |
||||
trap 'echo exiting; exit' INT |
||||
|
||||
# Main execution loop |
||||
while true; do |
||||
display_menu |
||||
done |
@ -0,0 +1,64 @@
|
||||
#!/bin/sh |
||||
|
||||
# Get Bitcoin sync status: 'syncing', 'synced', 'unknown', or 'error' |
||||
|
||||
. colors |
||||
|
||||
# Returns colored text based on status |
||||
color_for_status() { |
||||
case "$1" in |
||||
"installed, running, synced") |
||||
printf "${GREEN}" |
||||
;; |
||||
"not installed") |
||||
printf "${GRAY}" |
||||
;; |
||||
"installed, not running"|"installed, running, syncing"*|"installed, running, not synced") |
||||
printf "${YELLOW}" |
||||
;; |
||||
"installed, running, error"|"*") |
||||
printf "${RED}" |
||||
;; |
||||
esac |
||||
} |
||||
|
||||
get_sync_status() { |
||||
sync_status=$(bitcoin-cli getblockchaininfo 2>&1 | grep 'initialblockdownload' | awk '{print $2}' | tr -d ',') |
||||
if [ "$?" -ne "0" ]; then |
||||
echo "error" |
||||
elif [ "$sync_status" = "true" ]; then |
||||
echo "syncing" |
||||
elif [ "$sync_status" = "false" ]; then |
||||
echo "synced" |
||||
else |
||||
echo "unknown" |
||||
fi |
||||
} |
||||
|
||||
# Returns colored status message |
||||
get_status() { |
||||
if is-bitcoin-installed; then |
||||
if is-bitcoin-running; then |
||||
running_status="running" |
||||
sync_status=$(get_sync_status) |
||||
if [ "$sync_status" = "synced" ]; then |
||||
install_status="installed, $running_status, synced" |
||||
elif [ "$sync_status" = "syncing" ]; then |
||||
progress=$(bitcoin-cli getblockchaininfo | grep 'progress' | awk '{print int($2*100)}') |
||||
install_status="installed, $running_status, syncing $progress%" |
||||
elif [ "$sync_status" = "unknown" ]; then |
||||
install_status="installed, $running_status, not synced" |
||||
elif [ "$sync_status" = "error" ]; then |
||||
install_status="installed, $running_status, error" |
||||
fi |
||||
else |
||||
install_status="installed, not running" |
||||
fi |
||||
else |
||||
install_status="not installed" |
||||
fi |
||||
|
||||
printf "$(color_for_status "$install_status")$install_status${RESET}\n" |
||||
} |
||||
|
||||
get_status |
@ -0,0 +1,28 @@
|
||||
[Unit] |
||||
Description=Bitcoin daemon |
||||
After=network-online.target |
||||
Wants=network-online.target |
||||
|
||||
[Service] |
||||
Type=notify |
||||
NotifyAccess=all |
||||
ExecStart=BITCOIND --daemonwait --pid=HOME/.bitcoin/bitcoind.pid |
||||
|
||||
Type=forking |
||||
PIDFile=HOME/.bitcoin/bitcoind.pid |
||||
Restart=on-failure |
||||
TimeoutStartSec=infinity |
||||
TimeoutStopSec=600 |
||||
|
||||
KillSignal=SIGINT |
||||
LimitNOFILE=32768 |
||||
User=USER |
||||
Group=USER |
||||
|
||||
# Hardening |
||||
PrivateTmp=yes |
||||
PrivateDevices=yes |
||||
MemoryDenyWriteExecute=true |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
@ -0,0 +1,78 @@
|
||||
#!/bin/sh |
||||
|
||||
# This spell alters the location of thy Bitcoin data chamber on your system. |
||||
|
||||
# Check if a command needs to be re-invoked with sudo |
||||
retry_with_sudo() { |
||||
echo "Permission denied. Invoking the power of the super user..." |
||||
sudo "$@" |
||||
if [ $? -ne 0 ]; then |
||||
echo "Failed to execute with elevated privileges. Make certain thou hast the necessary permissions and try again." |
||||
exit 1 |
||||
fi |
||||
} |
||||
|
||||
# Check for the bitcoin.conf file |
||||
if [ ! -f "$HOME/.bitcoin/bitcoin.conf" ]; then |
||||
echo "Unable to locate bitcoin.conf. Canst thou provide its location?" |
||||
read bitcoin_conf |
||||
if [ ! -f "$bitcoin_conf" ]; then |
||||
echo "bitcoin.conf file not found at the provided location. The spell must end here." |
||||
exit 1 |
||||
fi |
||||
else |
||||
bitcoin_conf="$HOME/.bitcoin/bitcoin.conf" |
||||
fi |
||||
|
||||
# Get the current Bitcoin directory |
||||
current_directory=$(grep "datadir" "$bitcoin_conf" | cut -d'=' -f2) |
||||
if [ -z "$current_directory" ]; then |
||||
current_directory="$HOME/.bitcoin" |
||||
else |
||||
# Confirm that the directory actually exists |
||||
if [ ! -d "$current_directory" ]; then |
||||
echo "The Bitcoin data chamber specified in bitcoin.conf doth not exist. Please ensure the correctness of the 'datadir' value in bitcoin.conf." |
||||
exit 1 |
||||
fi |
||||
echo "Verified the existence of the Bitcoin data chamber at: $current_directory" |
||||
fi |
||||
|
||||
# Ask for the new directory |
||||
echo "Enter the new haven for thy Bitcoin data:" |
||||
read new_directory |
||||
|
||||
# Create the new directory if it does not exist |
||||
if [ ! -d "$new_directory" ]; then |
||||
mkdir "$new_directory" || retry_with_sudo mkdir "$new_directory" |
||||
fi |
||||
|
||||
# Ask user what to move |
||||
echo "What wouldst thou like to move to the new Bitcoin data haven?" |
||||
echo "1. The entire Bitcoin data chamber" |
||||
echo "2. Only the blockchain data" |
||||
echo "3. Move naught" |
||||
|
||||
read move_choice |
||||
|
||||
case "$move_choice" in |
||||
1) |
||||
echo "Moving the entire Bitcoin data chamber..." |
||||
mv "$current_directory"/* "$new_directory" || retry_with_sudo mv "$current_directory"/* "$new_directory" |
||||
;; |
||||
2) |
||||
echo "Moving only the blockchain data..." |
||||
mv "$current_directory/blocks" "$current_directory/chainstate" "$new_directory" || retry_with_sudo mv "$current_directory/blocks" "$current_directory/chainstate" "$new_directory" |
||||
;; |
||||
3) |
||||
echo "Moving naught..." |
||||
;; |
||||
*) |
||||
echo "Invalid choice, the spell ends here without moving anything." |
||||
exit 1 |
||||
;; |
||||
esac |
||||
|
||||
# Update the bitcoin.conf file to point to the new directory |
||||
awk -v path="$new_directory" '!/datadir/ {print} /datadir/ {$3 = path; print}' "$bitcoin_conf" | tee "$bitcoin_conf" >/dev/null || { retry_with_sudo awk -v path="$new_directory" '!/datadir/ {print} /datadir/ {$3 = path; print}' "$bitcoin_conf" | sudo tee "$bitcoin_conf" >/dev/null; } |
||||
|
||||
echo "The Bitcoin data chamber now resides in: $new_directory" |
@ -0,0 +1,105 @@
|
||||
#!/bin/sh |
||||
|
||||
# This spell facilitates the setting of the configurations for thy Bitcoin system. |
||||
|
||||
# Function to check if a command needs to be run with sudo |
||||
retry_with_sudo() { |
||||
echo "Permission denied. Invoking the power of the super user..." |
||||
sudo "$@" |
||||
if [ $? -ne 0 ]; then |
||||
echo "Failed to execute with elevated privileges. Make certain thou hast the necessary permissions and try again." |
||||
exit 1 |
||||
fi |
||||
} |
||||
|
||||
# Handle Ctrl-C |
||||
#trap "printf '\n'; exit 2" 2 |
||||
|
||||
# Create bitcoin directory and configuration file if they do not exist |
||||
mkdir -p "$HOME/.bitcoin" |
||||
touch "$HOME/.bitcoin/bitcoin.conf" |
||||
|
||||
# Bitcoin defaults |
||||
defaults="proxy=127.0.0.1:9050 |
||||
listen=1 |
||||
bind=127.0.0.1 |
||||
disablewallet=1 |
||||
zmqpubrawblock=tcp://127.0.0.1:28332 |
||||
zmqpubrawtx=tcp://127.0.0.1:28333" |
||||
|
||||
bitcoin_conf="$HOME/.bitcoin/bitcoin.conf" |
||||
|
||||
# If the file was just created (is empty), write defaults |
||||
if [ ! -s "$bitcoin_conf" ]; then |
||||
echo "$defaults" > "$bitcoin_conf" |
||||
else |
||||
ask_yn "Would you like to reset the bitcoin.conf file to defaults?" "n" |
||||
reset_conf=$? |
||||
if [ "$reset_conf" = 0 ]; then |
||||
echo "$defaults" > "$bitcoin_conf" |
||||
fi |
||||
fi |
||||
|
||||
# Function to modify bitcoin.conf using awk |
||||
modify_bitcoin_conf() { |
||||
local key=$1 |
||||
local value=$2 |
||||
awk -v key="$key" -v value="$value" 'BEGIN {found=0} !/^#/ && $1==key {found=1; print key"="value; next} {print} END {if (!found) print key"="value}' "$bitcoin_conf" > "$bitcoin_conf.tmp" && mv "$bitcoin_conf.tmp" "$bitcoin_conf" || retry_with_sudo mv "$bitcoin_conf.tmp" "$bitcoin_conf" |
||||
} |
||||
|
||||
# Pruning question and storage amount |
||||
ask_yn "Wouldst thou like to enable pruning? Pruning allows thee to reduce disk usage by discarding some transaction history." "y" |
||||
prune=$? |
||||
if [ "$prune" = 0 ]; then |
||||
modify_bitcoin_conf "prune" "1" |
||||
valid_number=false |
||||
while [ "$valid_number" = false ]; do |
||||
printf "What is the maximum disk space thou art willing to dedicate to Bitcoin in GB? (Type a number) [default: 500]: " |
||||
read -r max_disk |
||||
|
||||
if [ -z "$max_disk" ]; then |
||||
max_disk=500 |
||||
valid_number=true |
||||
elif validate_number "$max_disk"; then |
||||
valid_number=true |
||||
else |
||||
printf "Invalid input. Please enter a valid number.\n" |
||||
fi |
||||
done |
||||
|
||||
# Convert GB to MB |
||||
max_mem=$((max_disk * 1024)) |
||||
|
||||
modify_bitcoin_conf "dbcache" "$max_mem" |
||||
else |
||||
modify_bitcoin_conf "prune" "0" |
||||
fi |
||||
|
||||
# Network selection |
||||
ask_yn "Art thou operating on the main Bitcoin network?" "y" |
||||
mainnet=$? |
||||
if [ "$mainnet" = 0 ]; then |
||||
modify_bitcoin_conf "testnet" "0" |
||||
else |
||||
modify_bitcoin_conf "testnet" "1" |
||||
fi |
||||
|
||||
# Blockchain storage location |
||||
default_data_dir="$HOME/.bitcoin/blocks" |
||||
modify_bitcoin_conf "datadir" "$default_data_dir" |
||||
ask_yn "Wouldst thou like to store the blockchain in the default location ($default_data_dir)?" "y" |
||||
alt_storage=$? |
||||
if [ "$alt_storage" = 1 ]; then |
||||
while true; do |
||||
printf "Please type the alternate path thou wouldst like to use for blockchain storage: " |
||||
read -r alt_path |
||||
if validate_path "$alt_path"; then |
||||
break |
||||
else |
||||
printf "That's not a valid UNIX path string. " |
||||
fi |
||||
done |
||||
modify_bitcoin_conf "datadir" "$alt_path" |
||||
fi |
||||
|
||||
printf "Bitcoin configuration has been updated.\n" |
@ -0,0 +1,88 @@
|
||||
#!/bin/sh |
||||
|
||||
# This spell installs bitcoin on almost any Linux platform, from source when possible, otherwise from precompiled binary. |
||||
|
||||
# Set Bitcoin version |
||||
BITCOIN_VERSION=24.1 |
||||
|
||||
# Install Bitcoin from source |
||||
install_bitcoin_from_source() { |
||||
say "Installing Bitcoin Core from source" |
||||
if [ ! -e bitcoin-$BITCOIN_VERSION* ]; then |
||||
wget https://bitcoincore.org/bin/bitcoin-core-$BITCOIN_VERSION/bitcoin-$BITCOIN_VERSION.tar.gz |
||||
fi |
||||
. ./path_to_install_if_needed_script.sh boost |
||||
tar -xvf bitcoin-$BITCOIN_VERSION.tar.gz |
||||
sleep 1 |
||||
cd bitcoin-$BITCOIN_VERSION |
||||
chmod +x autogen.sh |
||||
./autogen.sh |
||||
./configure --disable-wallet |
||||
make |
||||
if [ $? -ne 0 ]; then |
||||
return 1 |
||||
fi |
||||
sudo make install |
||||
cd .. |
||||
return 0 |
||||
} |
||||
|
||||
# Install Bitcoin ARM precompiled binary |
||||
install_bitcoin_arm_binary() { |
||||
say "Installing Bitcoin Core ARM precompiled binary" |
||||
if [ ! -e bitcoin-$BITCOIN_VERSION* ]; then |
||||
wget https://bitcoincore.org/bin/bitcoin-core-$BITCOIN_VERSION/bitcoin-$BITCOIN_VERSION-arm-linux-gnueabihf.tar.gz |
||||
tar -xzf bitcoin-$BITCOIN_VERSION-arm-linux-gnueabihf.tar.gz |
||||
fi |
||||
sudo install -m 0755 -o root -g root -t /usr/local/bin bitcoin-$BITCOIN_VERSION/bin/* |
||||
} |
||||
|
||||
# Install Bitcoin x86_64 precompiled binary |
||||
install_bitcoin_x86_64_binary() { |
||||
say "Installing Bitcoin Core x86_64 precompiled binary" |
||||
if [ ! -e bitcoin-$BITCOIN_VERSION* ]; then |
||||
wget https://bitcoincore.org/bin/bitcoin-core-$BITCOIN_VERSION/bitcoin-$BITCOIN_VERSION-x86_64-linux-gnu.tar.gz |
||||
tar -xzf bitcoin-$BITCOIN_VERSION-x86_64-linux-gnu.tar.gz |
||||
fi |
||||
sudo install -m 0755 -o root -g root -t /usr/local/bin bitcoin-$BITCOIN_VERSION/bin/* |
||||
} |
||||
|
||||
# Install Bitcoin macOS precompiled binary |
||||
install_bitcoin_macos_binary() { |
||||
say "Installing Bitcoin Core macOS precompiled binary" |
||||
if [ ! -e bitcoin-$BITCOIN_VERSION* ]; then |
||||
wget https://bitcoincore.org/bin/bitcoin-core-$BITCOIN_VERSION/bitcoin-$BITCOIN_VERSION-osx-signed.dmg |
||||
hdiutil attach bitcoin-$BITCOIN_VERSION-osx-signed.dmg |
||||
cp -R /Volumes/Bitcoin-Core/Bitcoin-Qt.app /Applications/ |
||||
hdiutil detach /Volumes/Bitcoin-Core |
||||
fi |
||||
} |
||||
|
||||
# Detect the operating system |
||||
OS=$(uname -s) |
||||
|
||||
# Install Bitcoin based on the OS |
||||
case $OS in |
||||
Darwin) |
||||
install_bitcoin_macos_binary |
||||
;; |
||||
Linux) |
||||
ARCH=$(uname -m) |
||||
case $ARCH in |
||||
x86_64) |
||||
if ! install_bitcoin_from_source; then |
||||
install_bitcoin_x86_64_binary |
||||
fi |
||||
;; |
||||
arm* | aarch64) |
||||
install_bitcoin_arm_binary |
||||
;; |
||||
*) |
||||
say "Unsupported architecture: $ARCH" |
||||
exit |
||||
esac |
||||
;; |
||||
*) |
||||
say "Unsupported operating system: $OS" |
||||
exit |
||||
esac |
@ -0,0 +1,4 @@
|
||||
#!/bin/sh |
||||
|
||||
# Returns 0 (true) if Bitcoin is installed, 1 (false) if not |
||||
command -v bitcoin-cli >/dev/null 2>&1 |
@ -0,0 +1,16 @@
|
||||
#!/bin/sh |
||||
|
||||
# This script serves as a magic mirror, reflecting the running status of Bitcoin |
||||
|
||||
# Look for bitcoin process |
||||
if ps -e | grep -q '[b]itcoind'; then |
||||
if [ -t 1 ]; then # Check if output is a terminal |
||||
echo "Bitcoin is running." |
||||
fi |
||||
exit 0 # Bitcoin is running (success) |
||||
else |
||||
if [ -t 1 ]; then # Check if output is a terminal |
||||
echo "Bitcoin is not running." |
||||
fi |
||||
exit 1 # Bitcoin is not running (failure) |
||||
fi |
@ -0,0 +1,42 @@
|
||||
#!/bin/sh |
||||
|
||||
# This script sets the correct permissions on the Bitcoin configuration directory. |
||||
|
||||
# Set the default Bitcoin configuration directory |
||||
default_dir="$HOME/.bitcoin" |
||||
|
||||
# Check if the default directory exists |
||||
if [ -d "$default_dir" ]; then |
||||
bitcoin_dir="$default_dir" |
||||
else |
||||
# Prompt the user to enter the path to the Bitcoin configuration directory |
||||
read -p "Enter the path to the Bitcoin configuration directory: " bitcoin_dir |
||||
fi |
||||
|
||||
# Check if the provided directory exists |
||||
if [ -d "$bitcoin_dir" ]; then |
||||
# Set the default permission mode |
||||
default_mode=710 |
||||
|
||||
# Get the configuration directory mode from bitcoin.conf |
||||
config_mode=$(grep -E '^ConfigurationDirectoryMode=' "$bitcoin_dir/bitcoin.conf" | cut -d '=' -f 2) |
||||
|
||||
# If ConfigurationDirectoryMode is not specified, use the default mode |
||||
if [ -z "$config_mode" ]; then |
||||
config_mode=$default_mode |
||||
fi |
||||
|
||||
# Get the current permission mode of the directory |
||||
current_mode=$(stat -c "%a" "$bitcoin_dir") |
||||
|
||||
# Compare the current mode with the configured mode |
||||
if [ "$current_mode" != "$config_mode" ]; then |
||||
# Fix the permission by setting the correct mode |
||||
chmod "$config_mode" "$bitcoin_dir" |
||||
echo "The permission on the Bitcoin configuration directory has been set to $config_mode." |
||||
else |
||||
echo "The Bitcoin configuration directory is already configured with the correct permissions." |
||||
fi |
||||
else |
||||
echo "The provided directory does not exist." |
||||
fi |
@ -0,0 +1,70 @@
|
||||
#!/bin/sh |
||||
|
||||
# Function to check if a package is installed in Debian-based distributions |
||||
is_deb_package_installed() { |
||||
dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -c "ok installed" |
||||
} |
||||
|
||||
# Function to check if a package is installed in Redhat-based distributions |
||||
is_rpm_package_installed() { |
||||
rpm -q "$1" &> /dev/null |
||||
} |
||||
|
||||
# Function to check if a package is installed in Arch-based distributions |
||||
is_arch_package_installed() { |
||||
pacman -Q "$1" &> /dev/null |
||||
} |
||||
|
||||
# Uninstall Bitcoin from source |
||||
uninstall_bitcoin_from_source() { |
||||
say "Uninstalling Bitcoin Core installed from source" |
||||
sudo make uninstall |
||||
} |
||||
|
||||
# Uninstall Bitcoin package |
||||
uninstall_bitcoin_package() { |
||||
say "Uninstalling Bitcoin Core package" |
||||
|
||||
# Detect the operating system's package manager |
||||
if command -v apt &> /dev/null; then |
||||
if is_deb_package_installed bitcoin; then |
||||
sudo apt-get remove -y bitcoin |
||||
fi |
||||
elif command -v dnf &> /dev/null; then |
||||
if is_rpm_package_installed bitcoin; then |
||||
sudo dnf remove -y bitcoin |
||||
fi |
||||
elif command -v pacman &> /dev/null; then |
||||
if is_arch_package_installed bitcoin; then |
||||
sudo pacman -Rns bitcoin --noconfirm |
||||
fi |
||||
elif command -v brew &> /dev/null; then |
||||
if brew list --cask bitcoin-core; then |
||||
brew uninstall --cask bitcoin-core |
||||
fi |
||||
else |
||||
say "Unsupported package manager" |
||||
exit 1 |
||||
fi |
||||
} |
||||
|
||||
# Uninstall Bitcoin |
||||
uninstall_bitcoin() { |
||||
read -p "This will uninstall Bitcoin Core and might delete your wallet data. Are you sure? (Y/n) " yn |
||||
case $yn in |
||||
[Yy]* ) |
||||
uninstall_bitcoin_from_source |
||||
uninstall_bitcoin_package |
||||
;; |
||||
[Nn]* ) |
||||
say "Uninstallation cancelled" |
||||
;; |
||||
* ) |
||||
say "Invalid input. Please answer with Y (yes) or N (no)" |
||||
uninstall_bitcoin |
||||
;; |
||||
esac |
||||
} |
||||
|
||||
# Start the uninstallation |
||||
uninstall_bitcoin |
@ -0,0 +1,46 @@
|
||||
#!/bin/sh |
||||
|
||||
# This script serves as an "undo" scroll for the service installation script, |
||||
# removing a systemd service that was previously created |
||||
|
||||
if [ $# -lt 1 ]; then |
||||
echo "Usage: $0 service_name" |
||||
exit 1 |
||||
fi |
||||
|
||||
# Ensure systemd is available |
||||
if ! command -v systemctl >/dev/null 2>&1; then |
||||
echo "Systemd is not installed or not in PATH. Exiting." |
||||
exit 1 |
||||
fi |
||||
|
||||
service_dir=/etc/systemd/system |
||||
service_name=$1 |
||||
|
||||
# Add .service if not present in the name |
||||
case $service_name in |
||||
*.service) ;; |
||||
*) service_name="$service_name.service" ;; |
||||
esac |
||||
|
||||
service_path="$service_dir/$service_name" |
||||
|
||||
# Check if service file exists |
||||
if [ ! -f "$service_path" ]; then |
||||
echo "Service $service_name does not exist." |
||||
exit 1 |
||||
fi |
||||
|
||||
# Stop and disable service if it's running |
||||
if systemctl is-active --quiet "$service_name"; then |
||||
systemctl stop "$service_name" |
||||
fi |
||||
|
||||
# Remove the service file |
||||
sudo rm -f "$service_path" |
||||
|
||||
# Reload systemd |
||||
systemctl daemon-reload |
||||
|
||||
echo "Service $service_name removed." |
||||
exit 0 |
@ -0,0 +1,43 @@
|
||||
#!/bin/bash |
||||
|
||||
# A magical spell for slicing and dicing texts and lines. Reads a text file line by line and creates a new folder with the same name as the text file, with one file for each line in the text file inside that folder. Masks any characters that are not valid for use in Unix filenames. |
||||
|
||||
#!/bin/bash |
||||
|
||||
############################################################################### |
||||
# |
||||
# SCRIPT: slice_text_file.sh |
||||
# |
||||
# DESCRIPTION: A magical spell for slicing and dicing texts and lines. |
||||
# Reads a text file line by line and creates a new folder with the same name |
||||
# as the text file, with one file for each line in the text file inside that |
||||
# folder. Masks any characters that are not valid for use in Unix filenames. |
||||
# |
||||
# USAGE: slice_text_file.sh path/to/text_file.txt |
||||
# |
||||
############################################################################### |
||||
|
||||
# Check that a file path was provided as an argument |
||||
if [ "$#" -ne 1 ]; then |
||||
echo "Error: Please provide a file path as an argument." |
||||
exit 1 |
||||
fi |
||||
|
||||
# Create a folder with the same name as the text file |
||||
folder_name=$(basename "$1" | sed 's/\.[^.]*$//') |
||||
i=1 |
||||
while [ -d "$folder_name" ]; do |
||||
# If the folder already exists, append a number to the folder name |
||||
folder_name="$folder_name$i" |
||||
i=$((i+1)) |
||||
done |
||||
mkdir "$folder_name" |
||||
|
||||
# Read the text file line by line and create a file for each line |
||||
while read -r line; do |
||||
# Mask any characters that are not valid for use in Unix filenames |
||||
# Todo: file names are all prepended with the folder name (no slash), please fix so it's just the filename |
||||
file_name=$(echo "$line" | tr -dc '[:alnum:] .,;_-' | tr ' ' '_') |
||||
# Create the file |
||||
touch "$folder_name/$file_name" |
||||
done < "$1" |
@ -0,0 +1,38 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 01_navigating.sh |
||||
# To run the script, use the command: ./01_navigating.sh |
||||
echo "This spell that will teach you the basics of navigating the filesystem in POSIX-compliant Bash." |
||||
echo "To study the code of the examples, please use the command: cat 01_navigating.sh" |
||||
|
||||
echo "Casting 'pwd' command..." |
||||
echo "The 'pwd' command stands for 'print working directory' and it prints the current working directory." |
||||
pwd |
||||
|
||||
echo "Casting 'ls' command..." |
||||
echo "The 'ls' command stands for 'list' and it lists the files and directories in the current working directory." |
||||
ls |
||||
|
||||
echo "Casting 'cd' command with '/' argument..." |
||||
echo "The 'cd' command stands for 'change directory' and it changes the current working directory." |
||||
echo "This will take us to the root directory." |
||||
cd / |
||||
pwd |
||||
|
||||
echo "Casting 'cd' command with '~' argument..." |
||||
echo "This will take us to the home directory." |
||||
cd ~ |
||||
pwd |
||||
|
||||
echo "Casting 'mkdir' command..." |
||||
echo "The 'mkdir' command stands for 'make directory' and it creates a new directory." |
||||
echo "We are using the '-p' option which creates any necessary parent directories." |
||||
mkdir -p ~/wizardry/charms |
||||
ls ~/wizardry |
||||
|
||||
echo "Casting 'rmdir' command..." |
||||
echo "The 'rmdir' command stands for 'remove directory' and it removes an empty directory." |
||||
rmdir ~/wizardry/charms |
||||
ls ~/wizardry |
||||
rmdir ~/wizardry |
||||
|
||||
echo "Spell cast successfully." |
@ -0,0 +1,30 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 02_variables.sh |
||||
# To run the script, use the command: ./02_variables.sh |
||||
echo "This script is a spell that will teach you the basics of variables and parameter expansion in Bash." |
||||
echo "To study the code of the examples, please use the command: cat 02_variables_parameter_expansion.sh" |
||||
|
||||
# Declaring a variable |
||||
ingredient="Dragon's blood" |
||||
echo "Gathering ingredients for the potion, $ingredient found." |
||||
|
||||
# Accessing the value of a variable |
||||
echo "The ingredient used is: $ingredient" |
||||
|
||||
# Re-assigning a variable |
||||
ingredient="Unicorn hair" |
||||
echo "Gathering ingredients for the potion, $ingredient found." |
||||
|
||||
# Special variable: $# |
||||
echo "Number of ingredients passed to the script: $#" |
||||
|
||||
# Special variable: $@ |
||||
echo "All ingredients passed to the script: $@" |
||||
|
||||
# Special variable: $? |
||||
echo "Effect of the last ingredient added: $?" |
||||
|
||||
# Parameter expansion |
||||
echo "The first ingredient passed to the script is: ${1}" #todo: split this into another script, maybe between 01 and 02? |
||||
|
||||
echo "Spell cast successfully." |
@ -0,0 +1,55 @@
|
||||
#!/bin/sh |
||||
To make this script executable, use the command: chmod +x 14_boolean_comparison.sh |
||||
To run the script, use the command: ./14_boolean_comparison.sh |
||||
|
||||
echo "This spell will teach you the basics of boolean values and basic string comparison in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 14_boolean_comparison.sh" |
||||
Basic string comparison |
||||
|
||||
string1="magic" |
||||
string2="wizardry" |
||||
|
||||
echo "Are 'magic' and 'wizardry' the same? (Should be false)" |
||||
[ "$string1" = "$string2" ] |
||||
echo $? |
||||
|
||||
echo "Are 'magic' and 'magic' the same? (Should be true)" |
||||
[ "$string1" = "$string1" ] |
||||
echo $? |
||||
|
||||
echo "Is 'magic' not 'wizardry'? (Should be true)" |
||||
[ "$string1" != "$string2" ] |
||||
echo $? |
||||
|
||||
echo "Is 'magic' greater than 'wizardry'? (Should be false)" |
||||
[ "$string1" > "$string2" ] |
||||
echo $? |
||||
|
||||
echo "Is 'wizardry' greater than 'magic'? (Should be true)" |
||||
[ "$string2" > "$string1" ] |
||||
echo $? |
||||
|
||||
echo "Spell cast successfully" |
||||
|
||||
# To make this script executable, use the command: chmod +x 23_boolean_values.sh |
||||
# To run the script, use the command: ./23_boolean_values.sh |
||||
|
||||
echo "This spell will teach you the basics of boolean values and string comparison in POSIX-compliant Bash." |
||||
echo "To study the code of the examples, please use the command: cat 23_boolean_values.sh" |
||||
|
||||
# Basic boolean values |
||||
echo $((1 == 1)) # 0 |
||||
echo $((1 != 1)) # 1 |
||||
echo $((1 > 2)) # 1 |
||||
echo $((1 < 2)) # 0 |
||||
|
||||
# Basic string comparison |
||||
string1="Hello" |
||||
string2="World" |
||||
|
||||
echo $((string1 == string2)) # 0 |
||||
echo $((string1 != string2)) # 1 |
||||
echo $((string1 > string2)) # 1 |
||||
echo $((string1 < string2)) # 0 |
||||
|
||||
echo "Spell cast successfully" |
@ -0,0 +1,36 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 03_conditionals.sh |
||||
# To run the script, use the command: ./03_conditionals.sh |
||||
echo "This spell will teach you the basics of conditional statements in POSIX-compliant Bash." |
||||
echo "To study the code of the examples, please use the command: cat 03_conditionals.sh" |
||||
|
||||
# Using if statement |
||||
echo "Checking if the ingredient is Dragon's blood" |
||||
ingredient="Dragon's blood" |
||||
if [ "$ingredient" = "Dragon's blood" ]; then |
||||
echo "The ingredient is Dragon's blood, adding it to the potion" |
||||
else |
||||
echo "The ingredient is not Dragon's blood, adding something else to the potion" |
||||
fi |
||||
|
||||
# Using if-else statement |
||||
echo "Checking if the ingredient is Dragon's blood or Unicorn hair" |
||||
ingredient="Unicorn hair" |
||||
if [ "$ingredient" = "Dragon's blood" ]; then |
||||
echo "The ingredient is Dragon's blood, adding it to the potion" |
||||
elif [ "$ingredient" = "Unicorn hair" ]; then |
||||
echo "The ingredient is Unicorn hair, adding it to the potion" |
||||
else |
||||
echo "The ingredient is not Dragon's blood nor Unicorn hair, adding something else to the potion" |
||||
fi |
||||
|
||||
# Using test command |
||||
echo "Checking if the number of ingredients is greater than 5" |
||||
ingredients_count=6 |
||||
if test $ingredients_count -gt 5; then |
||||
echo "The number of ingredients is greater than 5" |
||||
else |
||||
echo "The number of ingredients is not greater than 5" |
||||
fi |
||||
|
||||
echo "Spell cast successfully." |
@ -0,0 +1,44 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 04_loops.sh |
||||
# To run the script, use the command: ./04_loops.sh |
||||
echo "To study the code of the examples, please use the command: cat 04_loops.sh" |
||||
echo "This spell will teach you the basics of loops in POSIX-compliant Bash" |
||||
|
||||
# Todo: give an example of using a for loop with both a number and an array (which is more like for-each) |
||||
|
||||
# A for loop continues looping for as many iterations as the number of things in "in" |
||||
echo "Iterating through ingredients" |
||||
ingredients=("Dragon's blood" "Unicorn hair" "Phoenix feather") |
||||
for ingredient in "${ingredients[@]}"; do |
||||
echo " Adding $ingredient to the potion" |
||||
done |
||||
|
||||
# A while loop continues as long as its test condition evaluates to true |
||||
echo "Iterating through numbers" |
||||
count=1 |
||||
while test $count -le 5; do |
||||
echo " Adding number $count to the potion" |
||||
count=$((count + 1)) |
||||
done |
||||
|
||||
# The 'break' keyword exits out of a loop |
||||
echo "Making a second potion, only adding ingredients up through Unicorn hair" |
||||
for ingredient in "${ingredients[@]}"; do |
||||
echo " Adding $ingredient to the potion" |
||||
if [ "$ingredient" = "Unicorn hair" ]; then |
||||
echo " Found Unicorn hair, this potion is finished." |
||||
break |
||||
fi |
||||
done |
||||
|
||||
# The 'continue' keyword skips ahead to the next loop iteration |
||||
echo "Making a third potion, skipping adding the Unicorn hair this time" |
||||
for ingredient in "${ingredients[@]}"; do |
||||
if [ "$ingredient" = "Unicorn hair" ]; then |
||||
echo " Found Unicorn hair, skipping adding this ingredient." |
||||
continue |
||||
fi |
||||
echo " Adding $ingredient to the potion" |
||||
done |
||||
|
||||
echo "Spell cast successfully" |
@ -0,0 +1,47 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 05_functions.sh |
||||
# To run the script, use the command: ./05_functions.sh |
||||
echo "This spell will teach you the basics of functions in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 05_functions.sh" |
||||
|
||||
# Defining a function |
||||
create_potion() { |
||||
echo "Creating potion with $1 and $2" |
||||
} |
||||
|
||||
# Calling a function |
||||
create_potion "Dragon's blood" "Unicorn hair" |
||||
|
||||
# Defining a function with return value |
||||
calculate_price() { |
||||
echo $((10 + 20)) |
||||
} |
||||
|
||||
# Calling a function with return value |
||||
price=$(calculate_price) |
||||
echo "Price of the potion is $price golds" |
||||
|
||||
echo "Functions can also be loaded in your .bashrc file to make them available in all terminals." |
||||
echo "For example, you can add the following line in your .bashrc file to load the 'hello' function: 'hello() { echo \"Hello, \$1\" }'" |
||||
|
||||
echo "Creating a function that changes the working directory" |
||||
go_to_spell_folder() { |
||||
cd ~/spells |
||||
pwd |
||||
} |
||||
|
||||
# Return statement |
||||
echo "The 'return' statement cause the function to return immediately. The return value can be captured in a variable." |
||||
my_function() { |
||||
echo "Inside the function" |
||||
return 5 |
||||
echo "This line will not be executed" |
||||
} |
||||
|
||||
echo "Before calling the function" |
||||
result=$(my_function) |
||||
echo "The function returned $result" |
||||
echo "After calling the function" |
||||
|
||||
echo "Spell cast successfully" |
||||
|
@ -0,0 +1,26 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 06_pipe.sh |
||||
# To run the script, use the command: ./06_pipe.sh |
||||
echo "This spell will teach you the basics of I/O redirection and pipelines in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 06_pipe.sh" |
||||
|
||||
# Redirecting standard output to a file |
||||
echo "The '>' operator redirects the output of the command to the left of it and writes it to the file on the right. If the file already exists, its contents will be overwritten." |
||||
echo "Dragon's blood" > ingredient.txt |
||||
|
||||
# Appending standard output to a file |
||||
echo "The '>>' operator works similar to '>', but it appends the output to the file instead of overwriting its contents." |
||||
echo "Appending to current_date.txt" >> current_date.txt |
||||
echo "Unicorn hair" >> ingredient.txt |
||||
|
||||
# Redirecting standard input from a file |
||||
echo "The '<' operator redirects the contents of the file on the right as the input for the command on the left." |
||||
echo "Content of current_date.txt:" |
||||
sort < ingredient.txt |
||||
|
||||
# Using pipelines |
||||
echo "The '|' operator takes the output of the command on the left and uses it as the input for the command on the right." |
||||
echo "All files in the current directory:" |
||||
ls -l | grep "^-" |
||||
|
||||
echo "Spell cast successfully." |
@ -0,0 +1,32 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 07_permissions.sh |
||||
# To run the script, use the command: ./07_permissions.sh |
||||
echo "This spell will teach you the basics of permissions in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 07_permissions.sh" |
||||
|
||||
# Execution flags |
||||
echo "The chmod command changes the permissions of a file. The permissions can be represented in two ways: octal or symbolic. " |
||||
echo "In octal representation, permissions are represented by a three-digit number, with each digit representing permissions for owner, group and others respectively. In this representation, 7 means read, write and execute permissions, 5 means read and execute permissions, and 0 means no permissions." |
||||
echo "In symbolic representation, permissions are represented by a combination of letters 'ugoa' (user, group, others, all) and '+-' (add or remove) and 'rwx' (read, write, execute) permissions. For example, 'ug+x' means add execute permission for user and group." |
||||
|
||||
echo "chmod +x script.sh adds the execution flag to a script" |
||||
touch my_script.sh |
||||
chmod +x my_script.sh |
||||
ls -l my_script.sh |
||||
echo "The file my_script.sh now has the execution flag set" |
||||
|
||||
echo "chmod 755 script.sh adds the execution flag and read and execute permissions for owner, group and others" |
||||
touch my_script2.sh |
||||
chmod 755 my_script2.sh |
||||
ls -l my_script2.sh |
||||
echo "The file my_script2.sh now has the execution flag and read and execute permissions for owner, group and others" |
||||
|
||||
echo "chmod 700 script.sh adds the execution flag and read, write and execute permissions for owner only" |
||||
touch my_script3.sh |
||||
chmod 700 my_script3.sh |
||||
ls -l my_script3.sh |
||||
echo "The file my_script3.sh now has the execution flag and read, write and execute permissions for owner only" |
||||
|
||||
echo "You can also use chown to change the ownership of a file." |
||||
echo "chown user:group script.sh changes the owner and group of the script.sh file" |
||||
echo "Spell cast successfully" |
@ -0,0 +1,41 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 08_regex.sh |
||||
# To run the script, use the command: ./08_regex.sh |
||||
echo "This spell will teach you the basics of regular expressions and pattern matching in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 08_regex.sh" |
||||
|
||||
# Basic regular expressions (special characters) |
||||
echo "Regular expressions are a way to search for patterns in text. Common special characters include:" |
||||
echo "^ - beginning of a line" |
||||
echo "$ - end of a line" |
||||
echo "* - any number of characters" |
||||
echo "? - any single character" |
||||
echo "[] - any character in the brackets" |
||||
echo "() - group characters together" |
||||
echo "| - or" |
||||
echo "\\ - escape special characters" |
||||
|
||||
# grep (search in text) |
||||
echo "The grep command searches for a pattern in a file or input." |
||||
echo "grep '^root:' /etc/passwd - searches for the pattern '^root:' in the file /etc/passwd" |
||||
echo "Example: grep 'bash' /etc/passwd - searches for the pattern 'bash' in the file /etc/passwd" |
||||
grep 'bash' /etc/passwd |
||||
|
||||
# sed (replace in text) |
||||
echo "The sed command is a stream editor that can perform basic text transformations on an input stream (a file or input from a pipeline)." |
||||
echo "sed 's/root/admin/' /etc/passwd - replaces the first occurence of 'root' with 'admin' in the file /etc/passwd" |
||||
echo "Example: sed 's/bash/zsh/' /etc/passwd - replaces the first occurence of 'bash' with 'zsh' in the file /etc/passwd" |
||||
echo "backup" | sed 's/backup/backup_file/' |
||||
|
||||
# awk (advanced text processing) |
||||
echo "The awk command is a text processing tool that can perform more complex text transformations." |
||||
echo "awk -F: '{ print $1 }' /etc/passwd - prints the first field of each line of the file /etc/passwd, where the field separator is ':'" |
||||
awk '{ print $1 }' /etc/passwd |
||||
echo "root:x:0:0:root:/root:/bin/bash" | awk -F: '{print $1}' |
||||
|
||||
# find and xargs (run command for all found files) |
||||
echo "The find command is used to search for files in a directory hierarchy. xargs is used to build and execute command lines from standard input." |
||||
echo "find / -name '*.txt' | xargs grep 'example' - searches for all .txt files in the root directory and its subdirectories, and runs 'grep 'example'' on each file found" |
||||
find /etc -name "*.conf" -exec grep "root" {} \; |
||||
|
||||
echo "Spell cast successfully" |
@ -0,0 +1,34 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 09_debugging.sh |
||||
# To run the script, use the command: ./09_debugging.sh |
||||
echo "This spell will teach you the basics of script debugging and error handling in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 09_debugging.sh" |
||||
|
||||
# echo and set -x (debugging) |
||||
echo "The echo command is used to print messages to the terminal. The set -x command enables the display of commands and their arguments as they are executed." |
||||
echo "Example: set -x; echo 'Debugging message'; set +x" |
||||
set -x; echo 'Debugging message'; set +x |
||||
|
||||
# trap and signal handling (error handling) |
||||
echo "The trap command is used to catch signals sent to the script. Signals are used to communicate with processes, and are typically sent when a program needs to terminate or interrupt another program." |
||||
echo "Example: trap 'echo Signal received, exiting...; exit 0' INT; sleep 10; echo 'This line will not be executed'" |
||||
trap 'echo Signal received, exiting...; exit 0' INT; sleep 10; echo 'This line will not be executed' |
||||
|
||||
# exit status and return values (error handling) |
||||
echo "Every command in Bash returns an exit status, which is the value that the command returns to the parent process. The value can be checked using the $? variable. A value of 0 indicates success, and any other value indicates failure." |
||||
echo "Example: echo $? (this should be 0)" |
||||
echo $? |
||||
|
||||
# Using the exit status in a conditional statement |
||||
command |
||||
if [ $? -eq 0 ]; then |
||||
echo "Command executed successfully" |
||||
else |
||||
echo "Command failed with exit status $?" |
||||
fi |
||||
|
||||
# Setting the exit status of the script |
||||
echo "You can also set the exit value of a script manually with the 'exit' command. 0 means success, every other value is an error. This script will exit with an error code of 42." |
||||
exit 42 |
||||
|
||||
echo "Spell cast successfully" |
@ -0,0 +1,19 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 10_aliases_functions.sh |
||||
# To run the script, use the command: ./10_aliases_functions.sh |
||||
echo "This spell will teach you the basics of Aliases and Functions in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 10_aliases_functions.sh" |
||||
|
||||
# Aliases |
||||
echo "Creating an alias for a command" |
||||
alias ll='ls -al' |
||||
ll |
||||
|
||||
echo "Aliases are used to create short, easy-to-remember commands for frequently used commands or sequences of commands." |
||||
echo "For example, we just created an alias 'll' for 'ls -al' command" |
||||
|
||||
echo "Creating an alias of an alias" |
||||
alias la='ll -a' |
||||
la |
||||
|
||||
echo "Spell cast successfully" |
@ -0,0 +1,29 @@
|
||||
#!/bin/sh |
||||
echo "This spell will teach you the basics of the eval and exec functions in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 11_eval.sh" |
||||
|
||||
# eval function |
||||
# The eval function takes a string as an argument and treats it as if it were a command. |
||||
# It allows the user to dynamically generate and execute commands. |
||||
|
||||
# Example 1: Using variables in a command |
||||
ingredient="Dragon's blood" |
||||
eval "echo Gathering ingredients for the potion: $ingredient" |
||||
|
||||
# Example 2: Using command substitution |
||||
eval "echo Today is $(date)" |
||||
|
||||
# Example 3: Using multiple commands |
||||
eval "echo Starting spell; sleep 2; echo Spell complete" |
||||
|
||||
# exec function |
||||
# The exec function also takes a command as its argument, but it replaces the current shell process with the new command. |
||||
# This means that the new command will not run in a subshell and any changes made by the new command will affect the current shell. |
||||
|
||||
# Example 1: Using exec to run a new shell |
||||
exec /bin/sh |
||||
|
||||
# Example 2: Using exec to run a command |
||||
exec echo "This command is being run by exec" |
||||
|
||||
echo "Spell cast successfully" |
@ -0,0 +1,21 @@
|
||||
#!/bin/sh |
||||
# This script is a spell that will teach you about the bg and fg commands in POSIX-compliant Bash |
||||
# To study the code of the examples, please use the command: cat 12_bg.sh |
||||
|
||||
echo "This spell will teach you about the bg and fg commands in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 12_bg.sh" |
||||
|
||||
# Running a command in the background |
||||
sleep 5 & |
||||
echo "Background task started. You can continue with other spells while waiting for it to finish." |
||||
|
||||
# Listing background tasks |
||||
jobs |
||||
|
||||
# Moving a background task to the foreground |
||||
fg %1 |
||||
echo "Background task is now in the foreground." |
||||
|
||||
# Sending a background task to the background |
||||
bg %1 |
||||
echo "Foreground task is now in the background." |
@ -0,0 +1,5 @@
|
||||
# To move the cursor to the beginning/end of the line, use the key combination: Ctrl+A/Ctrl+E |
||||
|
||||
# To delete the word before the cursor, use the key combination: Alt+Backspace |
||||
|
||||
# To delete the word after the cursor, use the key combination: Alt+D |
@ -0,0 +1,47 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 21_parentheses.sh |
||||
# To run the script, use the command: ./11_parentheses.sh |
||||
echo "This spell will teach you the basics of differentiating between similar parenthetical syntax in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 21_parentheses.sh" |
||||
|
||||
# Using $() command substitution |
||||
echo "Using command substitution with $()" |
||||
current_date=$(date) |
||||
echo "Today's date is: $current_date" |
||||
|
||||
# Using $(()) arithmetic expansion |
||||
echo "Using arithmetic expansion with $(())" |
||||
num1=5 |
||||
num2=3 |
||||
result=$((num1 + num2)) |
||||
echo "5 + 3 = $result" |
||||
|
||||
# Using string list |
||||
echo "Using string list with \"\"" |
||||
ingredients="Dragon's blood Unicorn hair Phoenix feather" |
||||
echo "Ingredients: $ingredients" |
||||
|
||||
# Using array |
||||
echo "Using array with ()" |
||||
ingredients=("Dragon's blood" "Unicorn hair" "Phoenix feather") |
||||
echo "Ingredients: ${ingredients[@]}" |
||||
|
||||
# Using [] test command |
||||
echo "Using test command with []" |
||||
string="Dragon's blood" |
||||
if [ "$string" = "Dragon's blood" ]; then |
||||
echo "The string is Dragon's blood" |
||||
else |
||||
echo "The string is not Dragon's blood" |
||||
fi |
||||
|
||||
# Using [[]] test command |
||||
echo "Using test command with [[]]" |
||||
string="Dragon's blood" |
||||
if [[ "$string" = "Dragon's blood" ]]; then |
||||
echo "The string is Dragon's blood" |
||||
else |
||||
echo "The string is not Dragon's blood" |
||||
fi |
||||
|
||||
echo "Spell cast successfully." |
@ -0,0 +1,10 @@
|
||||
#!/bin/sh |
||||
# To make this script executable, use the command: chmod +x 22_shebang.sh |
||||
# To run the script, use the command: ./22_shebang.sh |
||||
echo "This spell will teach you the basics of script execution headers in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 22_shebang.sh" |
||||
|
||||
# Shebang |
||||
echo "#!/bin/sh is the shebang, it specifies the interpreter to use for running the script" |
||||
echo "#!/usr/bin/env python is an alternative shebang to use for Python scripts" |
||||
echo "#!/usr/bin/env ruby is an alternative shebang to use for Ruby scripts" |
@ -0,0 +1,193 @@
|
||||
# Set command |
||||
echo "The set command is used to set or unset various shell options, as well as positional parameters." |
||||
|
||||
# Setting a shell option |
||||
echo "Here we are setting the -x option, which enables the display of commands and their arguments as they are executed." |
||||
set -x |
||||
echo "This line will be displayed in the terminal, as the -x option is set." |
||||
|
||||
# Unsetting a shell option |
||||
echo "Now we will unset the -x option, so command execution will no longer be displayed in the terminal." |
||||
set +x |
||||
echo "This line will not be displayed in the terminal, as the -x option is unset." |
||||
|
||||
# Setting positional parameters |
||||
echo "We can also use set to set the positional parameters." |
||||
set -- "one" "two" "three" |
||||
echo "Positional parameter 1: $1" |
||||
echo "Positional parameter 2: $2" |
||||
echo "Positional parameter 3: $3" |
||||
|
||||
echo "The set command allows for greater control over shell options and positional parameters." |
||||
echo "This spell will teach you about the 'set' command and different shell options in POSIX-compliant Bash" |
||||
echo "To study the code of the examples, please use the command: cat 07_variables.sh" |
||||
|
||||
# Setting shell options |
||||
echo "Setting the 'errexit' option, which exits the script if any command returns a non-zero exit status" |
||||
set -e |
||||
|
||||
# Using set -e to exit the script if a command fails |
||||
echo "Creating a file with touch command, which will not return a non-zero exit status" |
||||
touch example.txt |
||||
|
||||
echo "Creating a file with a non-existent command, which will return a non-zero exit status and cause the script to exit" |
||||
nonexistentCommand |
||||
|
||||
echo "This line will not be executed because the script exits on the previous command" |
||||
|
||||
# Unsetting shell options |
||||
echo "Unsetting the 'errexit' option" |
||||
set +e |
||||
|
||||
# Using set +e to continue the script even if a command fails |
||||
echo "Creating a file with a non-existent command, which will return a non-zero exit status but the script will continue" |
||||
nonexistentCommand |
||||
|
||||
echo "This line will be executed because the script does not exit on the previous command" |
||||
|
||||
echo "The spell has been cast successfully" |
||||
#!/bin/sh |
||||
# This script is a spell that will teach you about various shell options in POSIX-compliant Bash |
||||
# To study the code of the examples, please use the command: cat 12_shell_options.sh |
||||
|
||||
# Setting the -u option |
||||
echo "Setting the -u option: unset variables will cause an error" |
||||
set -u |
||||
|
||||
# Demonstrating the effect of the -u option |
||||
echo "Value of unset variable: $unset_variable" |
||||
|
||||
# Setting the -e option |
||||
echo "Setting the -e option: commands that return non-zero exit status will cause an error" |
||||
set -e |
||||
|
||||
# Demonstrating the effect of the -e option |
||||
echo "This command will fail: false" |
||||
|
||||
# Setting the -f option |
||||
echo "Setting the -f option: file name generation using wildcard characters will be disabled" |
||||
set -f |
||||
|
||||
# Demonstrating the effect of the -f option |
||||
echo "List of files: *" |
||||
|
||||
echo "Casting the spell is finished, check the code of the spell by using 'cat 12_shell_options.sh' command" |
||||
|
||||
# This script is a spell that will teach you about the n, v, and o options in POSIX-compliant Bash. |
||||
|
||||
# To study the code of the examples, please use the command: cat 12_shell_options_2.sh |
||||
|
||||
echo "This spell will teach you about the n, v, and o options in POSIX-compliant Bash" |
||||
|
||||
echo "Using the -n option to prevent execution of the commands" |
||||
set -n |
||||
echo "This line won't be executed" |
||||
set +n |
||||
|
||||
echo "Using the -v option to print commands before execution" |
||||
set -v |
||||
echo "This line will be printed before execution" |
||||
set +v |
||||
|
||||
echo "Using the -o option to set an option" |
||||
set -o nounset |
||||
echo "This line will trigger an error if the variable is not set" |
||||
set +o nounset |
||||
|
||||
echo "Casting the spell is finished, check the code of the spell by using 'cat 12_shell_options_2.sh' command" |
||||
|
||||
|
||||
# This script is a spell that will teach you about some additional shell options in POSIX-compliant Bash. |
||||
# To study the code of the examples, please use the command: cat script_name.sh |
||||
|
||||
# -u option: Treat unset variables as an error and exit |
||||
# This will cause the script to exit if an unset variable is used |
||||
set -u |
||||
echo "Using unset variable: $unset_variable" # This will cause the script to exit with an error |
||||
|
||||
# -C option: Prevent file overwriting with > |
||||
# This will cause the script to exit if the file already exists |
||||
set -C |
||||
echo "Hello World" > existing_file.txt # This will cause the script to exit with an error |
||||
|
||||
# -B option: Enable brace expansion |
||||
echo {a,b,c} # This will print "a b c" |
||||
echo {1..3} # This will print "1 2 3" |
||||
|
||||
# -e option: Exit immediately if a command exits with a non-zero status |
||||
set -e |
||||
ls does_not_exist.txt # This will cause the script to exit with an error |
||||
|
||||
echo "Casting the spell is finished, check the code of the spell by using 'cat script_name.sh' command" |
||||
|
||||
# This script is a spell that will teach you about some advanced shell options in POSIX-compliant Bash |
||||
|
||||
# -m: monitor mode |
||||
# This option will automatically exit the shell when all jobs have completed |
||||
set -m |
||||
sleep 10 & |
||||
wait |
||||
echo "All jobs have completed and the shell has exited" |
||||
|
||||
# -r: restricted mode |
||||
# This option will restrict the shell's abilities, making it more secure by disabling certain dangerous commands |
||||
set -r |
||||
echo "This line will be executed" |
||||
cp /etc/passwd /tmp/passwd # this command will be disabled and the script will exit with an error |
||||
echo "This line won't be executed" |
||||
|
||||
# -s: silent mode |
||||
# This option will make the shell more silent by not printing commands before they are executed |
||||
set -s |
||||
echo "This line will be executed" < |