You are not logged in.

#1 2023-01-08 19:46:15

NightOwl
Member
From: Netherlands
Registered: 2018-03-12
Posts: 23
Website

A few .bash_aliases functions I use

I don't know, maybe these kind of Bash script functions is already common knowledge for the users on this forum but I thought maybe someone might think they're interesting?

So I figured I'd post the functions I use in my '.bash_aliases' file here for anyone that might be interested in such a read, I hope I picked the right topic category for it? smile

I have them all gathered in Bash libraries on my GitHub Build repository that I'm slowly growing and adding things to as I'm learning or fiddling around with various stuffz.

 
#!/usr/bin/env bash
# # # # FUNCTIONS # # # # #
# Victor-ray, S <12261439+ZendaiOwl@users.noreply.github.com>
#
# Bash - Utility Functions
#

# A log function that uses log levels for logging different outputs
# Log levels
# -2: Debug
# -1: Info
#  0: Success
#  1: Warning
#  2: Error
log() {
  if [[ "$#" -gt 0 ]]
  then
    local -r LOGLEVEL="$1" TEXT="${*:2}" Z='\e[0m'
    if [[ "$LOGLEVEL" =~ [(-2)-2] ]]
    then
      case "$LOGLEVEL" in
        -2)
          local -r CYAN='\e[1;36m'
          printf "${CYAN}DEBUG${Z}: %s\n" "$TEXT"
          ;;
        -1)
          local -r BLUE='\e[1;34m'
          printf "${BLUE}INFO${Z}: %s\n" "$TEXT"
          ;;
        0)
          local -r GREEN='\e[1;32m'
          printf "${GREEN}SUCCESS${Z}: %s\n" "$TEXT"
          ;;
        1)
          local -r YELLOW='\e[1;33m'
          printf "${YELLOW}WARNING${Z}: %s\n" "$TEXT"
          ;;
        2)
          local -r RED='\e[1;31m'
          printf "${RED}ERROR${Z}: %s\n" "$TEXT"
          ;;
      esac
    else
      log 2 "Invalid log level: [Debug: -2|Info: -1|Success: 0|Warning: 1|Error: 2]"
    fi
  fi
}

# Displays 8 × 16-bit ANSI bold colours and a blinking effect
# \e[0;34m = Normal
# \e[1;34m = Bold
# \e[2;34m = Light
# \e[3;34m = Italic
# \e[4;34m = Underlined
# \e[5;34m = Blinking
# \e[6;34m = Blinking
# \e[7;34m = Background/Highlighted
# \e[8;34m = Blank/Removed
# \e[9;34m = Crossed over
# These can be combined, ex.
# \e[1;5;m = Blinking Bold
colour() {
  local -r Z='\e[0m' \
           COLOUR=('\e[1;37m' '\e[1;36m' '\e[1;35m' '\e[1;34m' '\e[1;33m' '\e[1;32m' '\e[1;31m' '\e[1;30m' '\e[5m' '\e[0m') \
           NAME=("WHITE" "CYAN" "PURPLE" "BLUE" "YELLOW" "GREEN" "RED" "BLACK" "BLINK" "RESET")
  local -r LENGTH="${#NAME[@]}"
  for (( C = 0; C < "$LENGTH"; C++ ))
  do
    printf "${COLOUR[$C]}%s${Z} \t%s\n" "${NAME[$C]}" "${COLOUR[$C]}"
  done
}

# Check if user ID executing script/function is 0 or not
isRoot() {
  if [[ "$EUID" -eq 0 ]]
  then
    log -1 "Is root"
    return 0
  else
    log -1 "Not root"
    return 1
  fi
}

# Checks if an argument parameter variable is an array or not
isArray() {
  if ! [[ "$#" -eq 1 ]]
  then
    log 2 "Requires 1 argument: [The variable to check if it's an array or not]"
    return 2
  elif ! declare -a "$1" &>/dev/null
  then
    log -1 "Not an array: $1"
    return 1
  else
    log -1 "Is an array: $1"
    return 0
  fi
}

# Gets the current time in UNIX & regular time (human-readable format)
getTime() {
  local -r UNIX=$(date +%s)
  local -r REGULAR=$(date -d @"$UNIX") LOCALEDATE=$(date +%x) LOCALETIME=$(date +%X)
  printf 'Regular: %s\nUnix: %s\nLocale´s Date: %s\nLocale´s Time: %s\n' "$REGULAR" "$UNIX" "$LOCALEDATE" "$LOCALETIME"
}

# Converts UNIX timestamps to regular human-readable timestamp
unixTimeToRegular() {
  if [[ "$#" -eq 1 ]]
  then
    local -r UNIXTIME="$1"
    local -r REGULAR=$(date -d @"$UNIXTIME")
    printf '%s\n' "$REGULAR"
    return 0
  else
    log 2 "Requires 1 argument: [UNIX Timestamp]"
    return 1
  fi
}

# Gets the locale's time definition
getLocaleTime() {
  if [[ "$#" -eq 0 ]]
  then
    date +%X
    return 0
  else
    log 2 "Requires no arguments"
    return 1
  fi
}

# Gets the locale's date definition
getLocaleDate() {
  if [[ "$#" -eq 0 ]]
  then
    date +%x
    return 0
  else
    log 2 "Requires no arguments"
    return 1
  fi
}

# Updates a Git repository directory and signs the commit before pushing with a message
updateGit() {
  local DIRECTORY MESSAGE COMMITMESSAGE
  local -r GPG_KEY_ID="<GPG Key ID>"
  if [[ "$#" -eq 1 ]] ; then
    DIRECTORY="$PWD"
    MESSAGE="$1"
  elif [[ "$#" -gt 1 ]] ; then
    DIRECTORY="$1"
    MESSAGE="${*:2}"
  fi
  (
    COMMITMESSAGE="࿓❯ $MESSAGE"
    local -r GIT_COMMIT_ARGS=(--signoff --gpg-sign="$GPG_KEY_ID" --message="$COMMITMESSAGE")
    git add "$DIRECTORY"
    git commit "${GIT_COMMIT_ARGS[@]}"
    git push
  )
}

# Checks if a command exists on the system
# Return status codes
# 0: Command exists on the system
# 1: Command is unavailable on the system
# 2: Missing command argument to check
hasCMD() {
  if [[ "$#" -eq 1 ]]
  then
    local -r CHECK="$1"
    if command -v "$CHECK" &>/dev/null
    then
      log -1 "Available"
      return 0
    else
      log -1 "Unavailable"
      return 1
    fi
  else
    log 2 "Requires 1 argument: [Command]"
    return 2
  fi
}

# Checks if a package exists on the system
# Return status codes
# 0: Package is installed
# 1: Package is not installed but is available in apt
# 2: Package is not installed and is not available in apt
# 3: Missing package argument to check
hasPKG() {
  if [[ "$#" -eq 1 ]]
  then
    local -r CHECK="$1"
    if dpkg-query --status "$CHECK" &>/dev/null
    then
      log -1 "Installed"
      return 0
    elif apt-cache show "$CHECK" &>/dev/null
    then
      log -1 "Not installed, install available"
      return 1
    else
      log -1 "Not installed, install unavailable"
      return 2
    fi
  else
    log 2 "Requires 1 argument: [Package name]"
    return 3
  fi
}

# Gets the name at the end of a path string after stripping the path 
getPathName() {
  if [[ ! "$#" -eq 1 ]]
  then
    log 2 "Requires 1 argument: [Path to get the name at the end of]"
  elif [[ ! -e "$1" ]]
  then
    log 2 "No such path: $1"
  else
    local DPATH="$1"
    printf '%s\n' "${DPATH##*/}"
  fi
}

# Converts a String to uppercase
upperCase() {
  if [[ "$#" -gt 0 && -n "$*" ]]
  then
    printf '%s\n' "${*^^}"
  else
    log 2 "Requires argument(s): [String(s) to make lowercase]"
  fi
}

# Converts a String to lower case
lowerCase() {
  if [[ "$#" -gt 0 && -n "$*" ]]
  then
    printf '%s\n' "${*,,}"
  else
    log 2 "Requires argument(s): [String(s) to make lowercase]"
  fi
}

# Installs package(s) using the package manager and pre-configured options
# Return codes
# 0: Install completed
# 1: Coudn't update apt list
# 2: Error during installation
# 3: Missing package argument
installPKG() {
  if [[ "$#" -eq 0 ]]
  then
    log 2 "Requires argument(s): [PKG(s) to install]"
    return 3
  else
    local -r PKG=("$@") OPTIONS=(--quiet --assume-yes --no-show-upgraded --auto-remove=true --no-install-recommends)
    local -r SUDOUPDATE=(sudo apt-get "${OPTIONS[@]}" update) \
             SUDOINSTALL=(sudo apt-get "${OPTIONS[@]}" install) \
             ROOTUPDATE=(apt-get "${OPTIONS[@]}" update) \
             ROOTINSTALL=(apt-get "${OPTIONS[@]}" install)
    if [[ ! "$EUID" -eq 0 ]]
    then
      if "${SUDOUPDATE[@]}" &>/dev/null
      then
        log 0 "Apt list updated"
      else
        log 2 "Couldn't update apt lists"
        return 1
      fi
      log -1 "Installing ${PKG[@]}"
      if DEBIAN_FRONTEND=noninteractive "${SUDOINSTALL[@]}" "${PKG[@]}"
      then
        log 0 "Installation completed"
        return 0
      else
        log 2 "Something went wrong during installation"
        return 2
      fi
    else
      if "${ROOTUPDATE[@]}" &>/dev/null
      then
        log 0 "Apt list updated"
      else
        log 2 "Couldn't update apt lists"
        return 1
      fi
      log -1 "Installing ${PKG[@]}"
      if DEBIAN_FRONTEND=noninteractive "${ROOTINSTALL[@]}" "${PKG[@]}"
      then
        log 0 "Installation completed"
        return 0
      else
        log 2 "Something went wrong during installation"
        return 1
      fi
    fi
  fi
}

# Uses $(<) to read a file to STDOUT, supposedly faster than cat.
readFile() {
  if [[ "$#" -eq 1 ]]
  then
    if [[ -f "$1" ]]
    then
      printf '%s\n' "$(<"$1")"
    else
      printf '%s\n' "Not a file"
    fi
  fi
}

# Shows the files in the current working directory's directory & all its sub-directories excluding hidden directories.
showDirFiles() {
  if [[ "$#" -eq 0 ]]
  then
    grep --files-with-matches --recursive --exclude-dir='.*' ''
    return 0
  else
    log 2 "Requires no arguments"
    return 1
  fi
}

# Counts the number of files recursively from current working directory
countDirFiles() {
  if [[ "$#" -eq 0 ]]
  then
    grep --recursive --files-with-matches --exclude-dir='.*' '' | wc -l
    return 0
  else
    log 2 "Requires no arguments"
    return 1
  fi
}

# Search for pattern in a specific file
findPatternInFile() {
  if ! [[ "$#" -eq 2 ]]
  then
    log 2 "Requires 2 argument: [Text pattern to find] [File to search]"
    return 2
  elif ! [[ -f "$2" ]]
  then
    log 2 "Not a file: $2"
    return 1
  else
    local -r PATTERN="$1" FILE="$2"
    grep "$PATTERN" "$FILE"
    return 0
  fi
}

# Search for a pattern recursively in files of current directory and its sub-directories
searchForPattern() {
  if [[ "$#" -gt 0 ]]
  then
    local -r PATTERN="$*"
    grep --recursive --exclude-dir '.*' "$PATTERN" 2>/dev/null
    return 0
  else
    log 2 "Requires minimum 1 argument and up: [Pattern(s) to locate]"
    return 1
  fi
}

# Search for files with pattern(s) recursively
getFilesWithPattern() {
  if [[ "$#" -gt 0 ]]
  then
    local -r PATTERN="$*"
    grep --files-with-matches --recursive --exclude-dir '.*' "$PATTERN" 2>/dev/null
    return 0
  else
    log 2 "Requires minimum 1 argument and up: [Pattern(s) to locate]"
    return 1
  fi
}

# Deletes a specified line in a file
deleteLineInFile() {
  if ! [[ "$#" -eq 2 ]]
  then
    log 2 "Requires 2 arguments: [Line number] [File]"
    return 3
  elif ! [[ "$1" =~ [0-9*] ]]
  then
    log 2 "Not a positive integer digit: $1"
    return 2
  elif ! [[ -f "$2" ]]
  then
    log 2 "Not a file: $2"
    return 1
  else
    local -r LINENR="$1" FILE="$2"
    sed -i ''"$LINENR"'d' "$FILE"
    return 0
  fi
}

# Deletes a specified range in a file
deleteRangeInFile() {
  if ! [[ "$#" -eq 3 ]]
  then
    log 2 "Requires 3 arguments: [Start of range] [End of range] [File]"
    return 3
  elif ! [[ "$1" =~ [0-9*] && "$2" =~ [0-9*] ]]
  then
    log 2 "Not a positive integer digit range: $1 & $2"
    return 1
  elif ! [[ -f "$3" ]]
  then
    log 2 "Not a file: $3"
    return 2
  else
    local -r START="$1" END="$2" FILE="$3"
    sed -i ''"$START"','"$END"'d' "$FILE"
    return 0
  fi
}

# Replaces a text pattern in a file with new text
replaceTextInFile() {
  if ! [[ "$#" -eq 3 ]]
  then
    log 2 "Requires 3 arguments: [Text to replace] [New text] [File]"
    return 2
  elif ! [[ -f "$3" ]]
  then
    log 2 "Not a file: $3"
    return 1
  else
    local -r FINDTEXT="$1" NEWTEXT="$2" FILE="$3"
    sed -i "s|${FINDTEXT}|${NEWTEXT}|g" "$FILE"
    return 0
  fi
}

# Appends text after line number
appendTextAtLine() {
  if ! [[ "$#" -eq 3 ]]
  then
    log 2 "Requires 3 arguments: [Line number] [Text to append] [File]"
    return 3
  elif ! [[ -f "$3" ]]
  then
    log 2 "Not a file: $3"
    return 2
  elif ! [[ "$1" =~ [0-9*] ]]
  then
    log 2 "Not a positive integer digit: $1"
    return 1
  else
    local -r LINENR="$1" TEXT="$2" FILE="$3"
    sed -i ''"$LINENR"'a '"$TEXT"'' "$FILE"
    return 0
  fi
}

# Appends text after matching text pattern
appendTextAtPattern() {
  if ! [[ "$#" -eq 3 ]]
  then
    log 2 "Requires 3 arguments: [Text pattern] [Text to append] [File]"
    return 2
  elif ! [[ -f "$3" ]]
  then
  	log 2 "Not a file: $3"
  	return 1
  else
    local -r PATTERN="$1" TEXT="$2" FILE="$3"
    sed -i '/'"$PATTERN"'/a '"$TEXT"'' "$FILE"
    return 0
  fi
}

# Appends text after the last line
appendTextAtLastLine() {
  if ! [[ "$#" -eq 2 ]]
  then
    log 2 "Requires 2 arguments: [Text to append] [File]"
    return 2
  elif ! [[ -f "$2" ]]
  then
    log 2 "Not a file: $2"
    return 1
  else
    local -r TEXT="$1" FILE="$2"
    sed -i '$a '"$TEXT"'' "$FILE"
    return 0
  fi
}

# Insert text before line number
insertTextAtLine() {
  if ! [[ "$#" -eq 3 ]]
  then
    log 2 "Requires 3 arguments: [Line number] [Text to insert] [File]"
    return 2
  elif ! [[ -f "$3" ]]
  then
    log 2 "Not a file: $3"
    return 1
  else
    local -r LINENR="$1" TEXT="$2" FILE="$3"
    sed -i ''"$LINENR"'i '"$TEXT"'' "$FILE"
    return 0
  fi
}

# Insert text before matching text pattern
insertTextAtPattern() {
  if ! [[ "$#" -eq 3 ]]
  then
    log 2 "Requires 3 arguments: [Text pattern] [Text to insert] [File]"
    return 2
  elif ! [[ -f "$3" ]]
  then
    log 2 "Not a file: $3"
    return 1
  else
    local -r PATTERN="$1" TEXT="$2" FILE="$3"
    sed -i '/'"$PATTERN"'/i '"$TEXT"'' "$FILE"
    return 0
  fi
}

# Inserts text before the last line
insertTextAtLastLine() {
  if ! [[ "$#" -eq 2 ]]
  then
    log 2 "Requires 2 arguments: [Text to insert] [File]"
    return 2
  elif ! [[ -f "$2" ]]
  then
    log 2 "Not a file: $2"
    return 1
  else
    local -r TEXT="$1" FILE="$2"
    sed -i '$i '"$TEXT"'' "$FILE"
    return 0
  fi
}

# Gets the length of an array
arrayLength() {
  if ! [[ "$#" -eq 1 ]]
  then
    log 2 "Requires 1 argument: [Array]"
    return 2
  elif ! declare -a "$1" &>/dev/null
  then
    log 2 "Not an array: $1"
    return 1
  else
    local -r ARR="$1"
    echo "${#ARR[@]}"
    return 0
  fi
}

# This function uses /dev/urandom to generate a password randomly.
# Default length is 36, another length can be specified by 1st argument value
genPassword() {
  # Ex. This one below uses the most commonly allowed password characters
  # < /dev/urandom tr -dc 'A-Z-a-z-0-9' | head -c${1:-32};echo;
  # 
  # Patterns ex.
  # 1: 'A-Za-z0-9'
  # 2: 'A-Za-z0-9{[#$@]}'
  # 3: 'A-Z a-z0-9{[#$@*-+/]}'
  # 4: 'A-Z a-z0-9<{[|?!~$#*-+/]}>'
  # 5: 'A-Z a-z0-9<{[|:?!#$@%+*^.~=,-]}>'
  # 6: 'A-Z a-z0-9<{[|:?!#$@%+*^.~,=()/\\;]}>'
  # 7: 'A-Z a-z0-9<{[|:?!#$@%+*^.~,-()/;]}>'
  # 8: 'A-Z a-z0-9<{[|:?!#$@%+*^.~,=()/\\;]}>'
  # 9: 'A-Z a-z0-9<{[|:?!#$@%+*^.~,-()/;/=]}>'
  # # # # # # # # # # # # # # # # # # # # # # #
  #< /dev/urandom tr -dc 'A-Z a-z0-9{[|:?!#$@%+*^.~,=()/\\;]}' | head -c"${1:-36}"; printf '\n';
  < /dev/urandom tr -dc 'A-Za-z0-9{[#$@]}' | head -c"${1:-36}"; printf '\n'
  return 0
}

# Generates a password using OpenSSL, default length is 36.
genOpenSSLPassword() {
  if hasCMD openssl &> /dev/null
  then
    openssl rand -base64 "${1:-36}"
    return 0
  else
    log 2 "OpenSSL command not available"
    return 1
  fi
}

# Records the output of a command to a file.
recordCommandOutput() {
  if [[ "$#" -eq 1 ]]
  then
    local -r COMMAND="$1" LOGFILE="log.txt"
    if test -f "$LOGFILE"
    then
      log -1 "$LOGFILE exists, appending to existing file"
      echo "Appending new output from $COMMAND" | tee -a "$LOGFILE"
      bash -c "$COMMAND" | tee -a "$LOGFILE"
      return 0
    else
      touch "$LOGFILE"
      bash -c "$COMMAND" | tee -a "$LOGFILE"
      log 0 "Command output recorded to $LOGFILE"
      return 0
    fi
  else
    log 2 "Requires 1 argument: [Command to record output of]"
    return 1
  fi
}

# Victor-ray, S <12261439+ZendaiOwl@users.noreply.github.com>
#
# Bash - Network Functions
#
# Test if a port is open or closed on a remote host
# Exit codes
# 1: Open
# 2: Closed
# 3: Invalid number of arguments
testRemotePort() {
  if [[ "$#" -eq 2 ]]
  then
    local -r HOST="$1" PORT="$2"
    if timeout 2.0 bash -c "true &>/dev/null>/dev/tcp/${HOST}/${PORT}"
    then
      log -1 "Open"
      return 0
    else
      log -1 "Closed"
      return 1
    fi
  else
    log 2 "Requires: [HOST] [PORT]"
    return 2
  fi
}

# Queries DNS record of a domain
getDNSRecord() {
  if [[ "$#" -gt 1 ]]
  then
    local -r DOMAIN="$1" RECORD="$2"
    dig "$DOMAIN" "$RECORD" +short
  else
    local -r DOMAIN="$1"
    dig "$DOMAIN" +short
  fi
}

# Gets the public IP for the network
getPublicIP() {
  local -r URLIPv4="https://ipv4.icanhazip.com" URLIPv6="https://ipv6.icanhazip.com"
  local -r IPv4=$(curl --silent --max-time 4 --ipv4 "$URLIPv4" 2>/dev/null || echo 'N/A') \
           IPv6=$(curl --silent --max-time 4 --ipv6 "$URLIPv6" 2>/dev/null || echo 'N/A')
  printf 'IPv4: %s\nIPv6: %s\n' "$IPv4" "$IPv6"
}

# Gets the local IP for the device
# IPv4, IPv6 & Link-local
getLocalIP() {
  if hasCMD jq &>/dev/null
  then
    ip -j address | jq '.[2].addr_info' | jq -r '.[].local'
  fi
}

# Gets all the local IP-addresses on the device
getAllLocalIP() {
  if hasCMD jq &>/dev/null
  then
    ip -j address | jq '.[].addr_info' | jq -r '.[].local'
  fi
}

# Tests for Public IPv4
# 0: Public IPv4 Available
# 1: Public IPv4 Unavailable
testPublicIPv4() {
  local -r URL="https://ipv4.icanhazip.com"
  if curl --silent --max-time 4 --ipv4 "$URL" &>/dev/null
  then
    log -1 "Available"
    return 0
  else
    log -1 "Unavailable"
    return 1
  fi
}

# Tests for Public IPv6
# 0: Public IPv6 Available
# 1: Public IPv6 Unavailable
testPublicIPv6() {
  local -r URL="https://ipv6.icanhazip.com"
  if curl --silent --max-time 4 --ipv6 "$URL" &>/dev/null
  then
    log -1 "Available"
    return 0
  else
    log -1 "Unavailable"
    return 1
  fi
}

# Gets the listening ports on the system
getListeningPorts() {
  if [[ "$EUID" -eq 0 ]]
  then
    grep 'LISTEN' <(lsof -i -P -n)
  else
    sudo lsof -i -P -n | grep 'LISTEN'
  fi
}

# Gets the services running on the network interfaces
getNetworkInterfaceServices() {
  if [[ "$EUID" -eq 0 ]]
  then
  	lsof -nP -i
  else
  	sudo lsof -nP -i
  fi
}

# Gets the HTML code for a URL with Bash TCP
# Reuires the host TCP server to listen on HTTP, not HTTPS 
getURL() {
  if [[ "$#" -eq 2 ]]
  then
    local -r HOST="$1" PORT="$2"
    exec 5<>/dev/tcp/"$HOST"/"$PORT"
    echo -e "GET / HTTP/1.1\r\nHost: ${HOST}\r\nConnection: close\r\n\r" >&5
    cat <&5
    return 0
  else
    log 2 "Requires: [HOST] [PORT]"
    return 1
  fi
}

Last edited by NightOwl (2023-01-13 22:27:18)

Offline

#2 2023-01-08 23:53:16

sleekmason
zoom
Registered: 2018-05-22
Posts: 1,108
Website

Re: A few .bash_aliases functions I use

I'm a fan.  Lot's of useful stuff there. Checking out the git update commands now.  Thanks for sharing.

Offline

#3 2023-01-09 04:51:22

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 12,652
Website

Re: A few .bash_aliases functions I use

Lots of interesting ideas here - thanks!

(And this is the right place to post stuff like this.)


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )

Introduction to the Bunsenlabs Boron Desktop

Offline

#4 2023-01-09 12:21:36

NightOwl
Member
From: Netherlands
Registered: 2018-03-12
Posts: 23
Website

Re: A few .bash_aliases functions I use

Nice, I'm glad it was liked ^^

I updated it a little so the functions use the log function in certain places for a little more colourized output

Offline

#5 2023-01-09 20:43:50

NightOwl
Member
From: Netherlands
Registered: 2018-03-12
Posts: 23
Website

Re: A few .bash_aliases functions I use

Added a few more that I wrote during the day when working on a PR for NextcloudPi

Offline

#6 2023-01-10 13:48:41

NightOwl
Member
From: Netherlands
Registered: 2018-03-12
Posts: 23
Website

Re: A few .bash_aliases functions I use

I've put them all in a GitHub Gist as well smile

It will probably be more up-to-date if I change anything or add more functions rather than the one here on the forum

Offline

#7 2023-01-11 06:59:58

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 12,652
Website

Re: A few .bash_aliases functions I use

For what it's worth, I posted some git terminal functions a while ago: https://forums.bunsenlabs.org/viewtopic.php?id=6690


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )

Introduction to the Bunsenlabs Boron Desktop

Offline

#8 2023-01-11 08:53:03

NightOwl
Member
From: Netherlands
Registered: 2018-03-12
Posts: 23
Website

Re: A few .bash_aliases functions I use

Cool

Thanks for sharing smile

Offline

Board footer

Powered by FluxBB