Last Updated: 4/11/2024 Created: 12/8/2020

Bash Utils - Draft

Prompt and read user input into a variable

read -p 'Please input your name: ' USER
read -sp 'Please input your password: ' PWD

Get Date time

NOW=`date +"%Y%m%d_%H%M%S"`

Protect against the last line not having a new line, while reading from a path

while read LINE || [ -n "$LINE" ]; do
    echo $LINE
done < "path/to/file" >/dev/null

Ignore changes in the amount of white space

diff -b $FILE1 $FILE2

Force kill

kill -9 <pid>

Get Base64 token

This can be used with npm config set to set the _auth value in .npmrc.

echo -n 'username:password' | base64

Use JavaScript for shell

Reference

  1. Put a shebang at the top of the file:
    #!/usr/bin/env node
    
  2. Make the script executable:
    chmod u+x myscript.js
    

Java Helpers

jps -l # List Java Processes

jstack -l <java-pid> # Sample call stacks

/usr/libexec/java_home # Get location of the JDK

Using Termenu

Install:

pip3 install termenu

Use:

$ echo -n "Would you like to exit? " && termenu -i Yes No Maybe

Random find/grep nodes

grep -r expression .
while read LINE; do grep function $LINE; done <<< `find . -type f -name "*.js"`
find . -type f -name "*.js" | xargs grep function
find . -type f -name “*.js” | xargs -P4 grep expression # parallel execution, max 4 procs
nvm_get_os ()
{
    local NVM_UNAME;
    NVM_UNAME="$(command uname -a)";
    local NVM_OS;
    case "$NVM_UNAME" in
        Linux\ *)
            NVM_OS=linux
        ;;
        Darwin\ *)
            NVM_OS=darwin
        ;;
        SunOS\ *)
            NVM_OS=sunos
        ;;
        FreeBSD\ *)
            NVM_OS=freebsd
        ;;
        AIX\ *)
            NVM_OS=aix
        ;;
    esac;
    nvm_echo "${NVM_OS-}"
}

Create folders and sub folders as needed

mkdir -p a/b/c

Bash Prompt example:

export PS1="\n\[\e[1;37m\]\t \[\e[1;33m\]\h \[\e[1;36m\]\w \[\e[1;31m\]\$(git_branch_text)\n\[\e[1;36m\]o>\[\e[0;37m\]"

Random Tips

  • local is only usable inside a function, outside, prefer to use declare
  • Use cat to conCATenate multiple files before sending to a processor like terser for JavaScript or csso for CSS.

Get OS details on macOS

$ /usr/bin/sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.7
BuildVersion:	19H15

Directory Service Command Line (dscl)

dscl # interactive mode, use cd to change directory, ls to list
dscl "/Active Directory/SFDC/All Domains" -list /Groups
dscl "/Active Directory/SFDC/All Domains" -read /Groups/CodeCollab

Another command to check out: dscacheutil

Identity

$ id -nG loz # All groups loz is in
SFDC\Domain Users localdb everyone ....

$ dsmemberutil checkmembership -U loz -G "SFDC\Domain Users"
user is a member of the group

NPM Run

function npmrun() {
  echo OPTIONS
  # Show all key/value pairs in the "scripts" section, removing first and last lines
  cat package.json | jq .scripts | tail +2 | sed '$d'
  echo "SELECT TO RUN:" 

  # 1. List all keys of scripts object on one line, strip all double-quotes
  # 2. Replace new-lines in above's output with spaces and save it in a variable
  list=$(cat package.json | jq '.scripts | keys | .[]' | sed 's/"//g' | tr -s "\n" " ") 
  COLUMNS=1 
  select sel in $list
  do 
    npm run $sel
    break
  done
}

Change password

sudo passwd centos # change password for the user centos

Line wrapping setting for the terminal

$ tput rmam # Disable line wrapping
$ tput smam # Enable line wrapping

If you run this script from the root of the project, it will create a new rootref folder that you can then include as an entry under directories in .bazelproject:

mkdir rootref; ls -1p | grep -v / | grep -v BUILD | grep -v bazel- | while read line; do bs=$(basename $line); ln -s $(pwd)/$bs $(pwd)/rootref/$bs; done

Force RSA key for SSH-KEYGEN

Specify the -m PEM option:

ssh-keygen -t rsa -b 4096 -m PEM

fzf

YouTube

Tips

  • Prefix search text with a single quote to enable exact match
  • Space-separated keywords (expressions) are ANDed
  • Negate keywords by prefixing them with exclamation point
  • keywords are case-insensitive by default

Calling long list on selected items

fzf | xargs ls -l   # Use tab/shift-tab to select multiple items (must enable multi mode first)

Go to folder of selected file

cd `fzf | xargs dirname`

Set Preview options

fzf --preview='[[ $(file --mime {}) =~ binary ]] && echo {} is a binary file || (bat --style=numbers --color=always {} || cat {}) 2> /dev/null | head -300'

Options

export PS_FORMAT="pid,ppid,user,pri,ni,vsz,rss,pcpu,pmem,tty,stat,args"

FD_OPTIONS="--follow --exclude .git --exclude node_modules"

#export FZF_DEFAULT_OPTS="--no-mouse --height 50% -1 --reverse --multi --inline-info --preview='[[ \$(file --mime {}) =~ binary ]] && echo {} is a binary file || (bat --style=numbers --color=always {} || cat {}) 2> /dev/null | head -300' --preview-window='right:hidden:wrap' --bind='f3:execute(bat --style=numbers {} || less -f {}),f2:toggle-preview,ctrl-d:half-page-down,ctrl-u:half-page-up,ctrl-a:select-all+accept,ctrl-y:execute-silent(echo {+} | pbcopy)'"
export FZF_DEFAULT_OPTS="--height 50% -1 --reverse --multi --inline-info --preview='[[ \$(file --mime {}) =~ binary ]] && echo {} is a binary file || (bat --style=numbers --color=always {} || cat {}) 2> /dev/null | head -300' --preview-window='right:hidden:wrap' --bind='f3:execute(bat --style=numbers {} || less -f {}),f2:toggle-preview,ctrl-d:half-page-down,ctrl-u:half-page-up,ctrl-a:select-all+accept,ctrl-y:execute-silent(echo {+} | pbcopy)'"

# Use git-ls-files inside git repo, otherwise fd
export FZF_DEFAULT_COMMAND="git ls-files --cached --others --exclude-standard I fd --type f --type l $FD_OPTIONS"
export FZF_CTRL_T_COMMAND="fd $FD_OPTIONS"
export FZF_ALT_C_COMMAND="fs --type d $FD_OPTIONS"

export BAT_PAGER="less -R"

Ctrl+R in bash: Reverse History search

URL Decode using Python

alias purldecode='python2 -c "import sys, urllib as ul; prin
t ul.unquote(sys.stdin.read());"'

Remove first and last characters

cat abc.txt | sed 's/^"//' | sed 's/"$//' > abc2.txt

Find occurrences of the keyword rimraf in package.json in the current directory and below

find . -type f -name "package.json" | xargs grep rimraf

Display contents of file.ext in current folder and immediate subfolders

find . -name file.ext -maxdepth 2 | xargs cat

Find file or folders that contain keyword

find . | grep KEYWORD

Get Folder sizes in kilobytes (-k) of all child folders (-d0) in the given pattern, sorted as numbers (-n) in reverse order (-r) using first column (-k1)

du -kd0 ~/sdb*/sdb* | sort -rnk1

Get total file sizes for each subfolder of the current folder (not block size)

for A in `ls -1p | grep -e "/$"`
do
    pushd "$A" >/dev/null
    pwd
    find . -type f -print0  | xargs -0 stat -f %z | awk '{t+=$1}END{print t}'
    popd >/dev/null
done

Assign default value to var

[[ -z $1 ]] && v1='default' || v1=$1

Fail Fast with message

function chexit() {
    # Check and exit if last return value is not 0, after echoing the message provided as the first argument.
    [[ $? != 0 ]] && echo "$1" && exit 1
}

Prompt for user input

read -p 'y/n ' RESP; [[ $RESP == 'y' ]] && echo 'y' || echo 'n'

Make an HTTP POST

curl

curl -X POST \
    -x PROXYHOST:PORT \
    -k \
    DESINATION_URL \
    --data 'key1=value1' \
    --data 'key2=value2' \
    --data-urlencode 'key3=value3'
    --data-urlencode 'key4=value4'

Time a command's duration

time

Strip substrings from a variable

Example: Substitute https with nothing:

URL_WITHOUT_HTTPS=$( echo ${URL//https:} )

Example: Substitute https with http:

URL='https://blah' && echo ${URL/https/http}

Create a multi-line file

Pick a keyword known not to exist in the contents of the file to be created, e.g. EOFKEY

cat << EOFKEY > FILENAME
LINE1
LINE2
...
EOFKEY

More Utility Scripts

https://github.com/alrra/dotfiles/blob/main/src/os/utils.sh

Grep replacement

rg

Using sed to replace lines in place

sed -i '' -E 's/^REPLACETHIS.+$/WITHTHIS/g' FILENAME

Sorted list of files (folders shown first, includes coloring)

script -q /dev/null ls -hpGol1 | sort

Replace back-tick with newline?

sed $'s/`/\\\n/g'

SSH using key example

alias sshvm='ssh -i ~/vm.key vm@IP.AD.DR.ESS'

All function arguments but the first one:

  • "${@:2}" - retains new lines
  • "${*:2}" - runs all of the arguments together as a single argument with spaces

List Functions

  • typeset -f
  • typeset -F

POST file to a URL

curl -v -H"Content-Type:text/plain" -d "@sampleCoreEnvelope.txt" "http://localhost:3002/api/uitelemetry_csv"

Count how many colors xterm actually supports

xterm-color-count.sh

Remove app from security quarantine on macOs

xattr -d com.apple.quarantine ./FILENAME

More ... (Still to document)

dirname
basename
yes
pkg=$(cat package.json) && echo <"$pkg"

Grep except pattern

Use the -v argument. eg:

find . -name '*.js' | grep -v '/node_modules/' | grep -v '/dist/'

Replace something in XML

xq -x --xml-dtd ".SOME.JQ.PATH=\"$NEW_VALUE\"" INPUT.XML >OUTPUT.XML

Which shell am I really using?

ps -p $$
# Take the value from under the "CMD" column, e.g. sh
type sh
# Take the path, e.g. /bin/sh
ls /bin/sh
# Check to see if it's a sybolic link directing to, say, bash

Which OS am I running on?

uname # on MacOS: Darwin

What is the name of the computer?

uname -n

The following snippet creates symbolic links inside rootref for files in the current folder, excepting certain filenames:

 mkdir rootref; ls -1p | grep -v / | grep -v BUILD | grep -v bazel- | grep -v WORKSPACE | while read line; do bs=$(basename $line); ln -s $(pwd)/$bs $(pwd)/rootref/$bs; done