Display echo Hello World print on screen echo -n "Hello, World!" no new line Files display ls show files ls -a with hidden files ls -l table view ls -lh size in human format ls | wc -l number of files in dir Show path pwd shows where you are Go to cd / root directory cd home directory cd ~ same cd .. 1 level up .. same (on mac) cd ../.. 2 levels up cd - back cd path go to path cd /var/www/html/ go to on unix cd c:/Users/sherb/Git/ go to on win cd /C/ go to C drive on win Read cat file_path show file content in terminal nano file_name.txt read file in nano editor vi file_name.txt read file in vi editor Move content cat file_path_1 > file_path_2 put file_1 content into file_2 ls file_path_1 > file_path_2 put file names at path_1 to the file at path_2 echo string >> file_path add "string" to the end of the file Create folder mkdir folder_name create folder Create file touch file_name.txt create file > file_name.txt same nano file_name.txt create and open file in nano editor vi file_name.txt create and open file in vi editor Copy cp /path_from /path_to copy a file cp -a /path_from/ . /path_to/ copy all from folder to another folder scp -r /path_from/ sherb@35.209.92.93:/var/www/html/folder_name copy folder to server via ssh scp -r sherb@35.209.92.93:/var/www/html/folder_name ~/Temp copy folder from server via ssh Move mv /file_path_from /file_path_to move a file Rename mv /file_or_folder_path_from /file_or_folder_path_to move & rename mv ./file_or_folder_path_from ./file_or_folder_path_to rename in the same folder Remove rm -r folder_path remove folder with warnings rm -rf folder_path remove folder without warnings rm -rf *.zip remove files with .zip ext rm * remove all files in folder with warnings rm -f * remove all files in folder without warnings Tar tar czvf ~/Temp/archive.tar.gz -C ~/Temp/ xxx yyy hi.txt archive listed folders and files from ~/Temp/ and put into ~/Temp/archive.tar.gz tar -xf ~/Temp/archive.tar.gz -C ~/Temp/extracted extract the archive archive.tar.gz from folder ~/Temp/ into folder ~/Temp/extracted Zip tar -xvf file_name.tar untar archive file sudo apt install zip unzip install zip zip -r file_name.zip path zip folder with full path zip -r path/file_name.zip ./* zip folder without full path Documentation man command_name documentation for a command Sudo sudo -s stay sudo permanently (Super User DO) sudo !! Run the previous command with sudo Size df -h size of disk du -h path size of folder Open with open . open with finder (mac) start . open with explorer (win) code . open with VSCode new instance code -a . open with VSCode same instance User whoami user name cat /etc/passwd list of users su user_name change user Permission sudo chmod -R 777 /path/. set the permissions recursively sudo chmod -R 777 /var/www/myVocabGitRemoteRepo/. example sudo chmod +x ./file_path make file executable Apps sudo apt install app_name_1 app_name_2 install app on linux sudo apt update latest info about the apps apt list --upgradable list of upgradable apps sudo apt upgrade upgrade all apps that have a newer version sudo apt-get --only-upgrade install app_name install upgrade for the app Reboot sudo reboot reboot Git git add . && git commit -m 'message' && git push git add, commit & push Alias For Bash nano ~/.bashrc code ~/.zshrc Add some shortcuts
# Aliases
# alias alias_name="command_to_run"
# Long format list
alias ll="ls -la"
alias cl="clear && printf '\e[3J'" # clear with history
alias start="npm run start"
alias test="npm run test"
alias lint="npm run lint"
alias tsc="npx tsc"
alias vpnoff="launchctl unload /Library/LaunchAgents/com.paloaltonetworks.gp.pangp*"
alias vpnon="launchctl load /Library/LaunchAgents/com.paloaltonetworks.gp.pangp*"
# Print my public IP
alias myip='curl ipinfo.io/ip'
# Function to create a folder and navigate into it
function mkcd () {
mkdir -p -- "$1" && cd -P -- "$1"
}
Add aliases to your current session source ~/.zshrc Execute source filename executes the content of the file in the current shell . /opt/nvm/nvm.sh dot is the alias for the source command /opt/nvm/nvm.sh also executes if file is executable which can be done by sudo chmod +x ./file_path SSH ssh sherb@35.217.12.143 connect cd /var/www/html/antonarbus.com go to web page folder Keyboard Ctrl + L clean terminal, same as clear Alt + click put cursor close to the click Arrow_Up previous command Ctrl + C exit Ctrl + D log out Ctrl + U delete line Ctrl + A move cursor to the beginning Ctrl + E move cursor to the end Ctrl + Left / Right move cursor one word Search Ctrl + R search command in terminal history Ctrl + R (again) previous found command Ctrl + O or Enter paste found command & execute Ctrl + G exit & remove found command Arrow Left exit & leave found command Ctrl + G exit search mode history show history commands Process on port sudo lsof -i :3000 check PID of process on port 3000 Kill the process kill -9 PID kill the process End of option arguments rm -f -- "file.txt" signify the end of the options with two hyphens Time & date date show date date +"%Y-%m-%d %H:%M:%S" time in YYYY-MM-DD HH:MM:SS format Prompt Native stdin way
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
});
readline.question(`What's your name?`, name => {
console.log(`Hi ${name}!`);
readline.close();
});
With inquirer package A more complete and abstract solution is provided by the Inquirer.js package. It is even mentioned on the Node.js website
const inquirer = require('inquirer');
const questions = [
{
type: 'input',
name: 'name',
message: "What's your name?",
},
];
inquirer.prompt(questions).then(answers => {
console.log(`Hi ${answers.name}!`);
});
Used it ones to create a selection list
const inquirer = require('inquirer')
const devDeploy = async () => {
const lambdaDirs = await getLambdaDirs()
const { dirs } = await inquirer.prompt([{
type: 'checkbox',
message: 'Lambdas',
name: 'dirs',
prefix: '
',
pageSize: 30,
loop: false,
choices: lambdaDirs.map(lambdaDir => ({ name: lambdaDir, checked: true }))
}])
const { actions } = await inquirer.prompt([{
type: 'checkbox',
message: 'Actions',
name: 'actions',
prefix: '
',
choices: [
{ name: 'lint', checked: true },
{ name: 'npm ci', checked: true },
{ name: 'test', checked: true },
{ name: 'zip', checked: true },
{ name: 'zip to desktop', checked: false },
{ name: 're-deploy template', checked: true }
]
}])
if (actions.includes('lint')) {
await lint()
}
if (actions.includes('npm ci')) {
await npmCi({ dirs })
}
if (actions.includes('test')) {
await test({ dirs })
}
if (actions.includes('zip')) {
await zip({ dirs })
}
if (actions.includes('zip to desktop')) {
await zipToDesktop({ dirs })
}
if (actions.includes('re-deploy template')) {
await builtTemplateYaml()
const packageName = await getPackageName()
await packagedTemplateYaml({ packageName })
deploy({ packageName })
}
}
Executable location which bash path of bash app executable on the system /bin/bash Variables Uppercase by convention Persisted in terminal session Use money sign to reference a variable
NAME="John"
echo $NAME # John
echo "$NAME" # John
echo ${NAME} # John
echo "${NAME}!" # John!
echo '$NAME' # $NAME (Exact string)
NAME = "John" # Error (about space)
Script file touch ./script.sh create script file
# path to bash executable, can be checked with 'which bash'
#! /bin/bash
# print
echo Hello world!
bash ./script.sh execute the script Executable script chmod +x ./script.sh make script executable ./myscript.sh run the script without bash command Comments Line comment starts with hash sign Multi-line comments use :' to open and ' to close
# This is an inline Bash comment
: '
This is a
very neat comment
in bash
'
Shell execution
echo "I'm in $(PWD)"
echo "I'm in `pwd`" # Same as:
Brace expansion
echo {A,B} # A B
echo {A,B}.js # A.js B.js
echo {1..5} # 1 2 3 4 5
String replacement
# Remove Suffix
TEXT="example.txt"
echo ${TEXT%.txt} # Output: example (removes the last suffix .txt)
# Remove Prefix
TEXT="prefix_example"
echo ${TEXT#prefix} # Output: _example (removes the 'prefix')
# Remove Long Suffix
TEXT="example.txt.bak"
echo ${TEXT%%.*} # Output: example (removes everything from the first dot to the end)
# Remove Long Prefix
TEXT="prefix_example_text"
echo ${TEXT##prefix_} # Output: example_text (removes everything up to the last 'prefix_')
# Replace First Match
TEXT="hello world"
echo ${TEXT / h / H} # Output: Hello world
# Replace All
TEXT="hello world world"
echo ${TEXT//world/universe} # Output: hello universe universe (replaces all 'world' with 'universe')
# Replace Suffix
TEXT="file.txt"
echo ${TEXT/%txt/doc} # Output: file.doc (replaces 'txt' suffix with 'doc')
# Replace Prefix
TEXT="hello_world"
echo ${TEXT/#hello/hi} # Output: hi_world (replaces 'hello' prefix with 'hi')
Slicing
name="John"
echo ${name} # => John
echo ${name:0:2} # => Jo
echo ${name::2} # => Jo
echo ${name::-1} # => Joh
echo ${name:(-1)} # => n
echo ${name:(-2)} # => hn
echo ${name:(-2):2} # => hn
Length
# Length of TEXT
TEXT="example"
echo ${#TEXT} # Output: 7 (length of the string)
Text transform
STR="HELLO WORLD!"
echo ${STR,} # => hELLO WORLD!
echo ${STR,,} # => hello world!
STR="hello world!"
echo ${STR^} # => Hello world!
echo ${STR^^} # => HELLO WORLD!
ARR=(hello World)
echo "${ARR[@],}" # => hello world
echo "${ARR[@]^}" # => Hello World
BASE_PATH
SRC="/path/to/foo.cpp"
BASE_PATH=${SRC##*/}
echo $BASE_PATH # => "foo.cpp"
DIR_PATH
SRC="/path/to/foo.cpp"
DIR_PATH=${SRC%$BASEPATH}
echo $DIR_PATH # => "/path/to/"
THIS_DIR
THIS_DIR="${0%/*}"
Relative path
THIS_DIR="${0%/*}"
echo "${THIS_DIR}/../share/foo.sh"
Define array
Fruits=('Apple' 'Banana' 'Orange')
Fruits[0]="Apple"
Fruits[1]="Banana"
Fruits[2]="Orange"
ARRAY1=(foo{1..2}) # => foo1 foo2
ARRAY2=({A..D}) # => A B C D
# Merge => foo1 foo2 A B C D
ARRAY3=(${ARRAY1[@]} ${ARRAY2[@]})
Index array
Fruits=('Apple' 'Banana' 'Orange')
${Fruits[0]} First element --> Apple
${Fruits[*]} All elements --> Apple Banana Orange
${Fruits[@]} All elements --> Apple Banana Orange
${#Fruits[@]} Number of all --> 3
${#Fruits} Length of 1st --> 5
${#Fruits[2]} Length of 2nd --> 6
${Fruits[@]:1:2} Range --> Banana Orange
${!Fruits[@]} Keys of all --> 0 1 2
Iteration over array
Fruits=('Apple' 'Banana' 'Orange')
for e in "${Fruits[@]}"; do
echo $e
done
# Apple
# Banana
# Orange
# With index
for i in "${!Fruits[@]}"; do
printf "%s %s
" "$i" "${Fruits[$i]}"
done
# 0 Apple
# 1 Banana
# 2 Orange
Array operations
Fruits=("${Fruits[@]}" "Watermelon") # Push
Fruits+=('Watermelon') # Also Push
Fruits=( ${Fruits[@]/Ap*/} ) # Remove by regex match
unset Fruits[2] # Remove one item
Fruits=("${Fruits[@]}") # Duplicate
Fruits=("${Fruits[@]}" "${Veggies[@]}") # Concatenate
Dictionary
# works from version 4 (check with bash --version)
# declare
declare -A sounds
sounds[dog]="bark"
sounds[cow]="moo"
sounds[bird]="tweet"
sounds[wolf]="howl"
# access
echo ${sounds[dog]} # Dog's sound
echo ${sounds[@]} # All values
echo ${!sounds[@]} # All keys
echo ${#sounds[@]} # Number of elements
unset sounds[dog] # Delete dog
# iterate
for val in "${sounds[@]}"; do
echo $val
done
for key in "${!sounds[@]}"; do
echo $key
done
User input
read -p "Enter your age: " AGE
echo "you are $AGE years old"
If statement
#! /bin/bash
NAME="Anton"
# if statement
if [ "$NAME" == "Anton" ]
then
echo "Your name is Anton"
fi
NAME="John"
# if-else statement
if [ "$NAME" == "Anton" ]
then
echo "Your name is Anton"
else
echo "Your name is not Anton"
fi
NAME="Jack"
# else-if statement
if [ "$NAME" == "Anton" ]
then
echo "Your name is Anton"
elif [ "$NAME" == "Jack" ]
then
echo "Your name is Jack"
else
echo "Your name is not Anton or Jack"
fi
Case statement
# example 1
echo "Enter a number between 1 and 3:"
read NUMBER
case $NUMBER in
1)
echo "You chose 1!"
;;
2)
echo "You chose 2!"
;;
3)
echo "You chose 3!"
;;
*)
echo "Invalid choice, please enter a number between 1 and 3."
;;
esac
# example 2
read -p "Are you 21 or over? Y/N " ANSWER
case "$ANSWER" in
[yY] | [yY][eE][sS])
echo "You can have a beer :)"
;;
[nN] | [nN][00])
echo "Sorry, no drinking"
;;
*)
echo "Please enter y/yes or n/no"
;;
esac
Conditions
[[ X && Y ]] # And
[[ X -a Y ]] # And
[[ X || Y ]] # Or
[[ X -o Y ]] # Or
[[ ! EXPR ]] # Not
# example
if [[ X && Y ]]; then
...
fi
if [ "$1" = 'y' -a $2 -gt 0 ]; then
echo "yes"
fi
if [ "$1" = 'n' -o $2 -lt 0 ]; then
echo "no"
fi
Comparison
# NUMERICAL comparison
[[ NUM -eq NUM ]] # Equal
[[ NUM == NUM ]] # Equal
[[ NUM -ne NUM ]] # Not equal
[[ NUM -lt NUM ]] # Less than
(( NUM < NUM )) # Less than
[[ NUM -le NUM ]] # Less than or equal
(( NUM <= NUM )) # Less than or equal
[[ NUM -gt NUM ]] # Greater than
(( NUM > NUM )) # Greater than
[[ NUM -ge NUM ]] # Greater than or equal
(( NUM >= NUM )) # Greater than or equal
# example
NUM1=3
NUM2=5
if [[ "$NUM1" -gt "$NUM2" ]]
then
echo "$NUM1 is greater than $NUM2"
else
echo "$NUM1 is less than $NUM2"
fi
String comparison
# STRING comparison
[[ STR == STR ]] # Equal
[[ STR = STR ]] # Equal (Same above)
[[ STR < STR ]] # Less than (ASCII)
[[ STR > STR ]] # Greater than (ASCII)
[[ STR != STR ]] # Not Equal
[[ STR =~ STR ]] # Regexp
[[ -z STR ]] # Empty string
[[ -n STR ]] # Not empty string
# example
if [[ "$A" == "$B" ]]; then
...
fi
if [[ '1. abc' =~ ([a-z]+) ]]; then
echo ${BASH_REMATCH[1]}
fi
if (( $a < $b )); then
echo "$a is smaller than $b"
fi
Files conditions
# FILE CONDITIONS
[[ -e FILE ]] # Checks if the file exists.
[[ -d FILE ]] # Checks if FILE is a directory.
[[ -f FILE ]] # Checks if FILE is a regular file. Returns true if FILE exists and is a file, not a directory or symlink.
[[ -h FILE ]] # Checks if FILE is a symbolic link (symlink).
[[ -s FILE ]] # Checks if FILE has non-zero size. Returns true if FILE exists and has a size greater than 0 bytes.
[[ -r FILE ]] # Checks if FILE is readable.
[[ -w FILE ]] # Checks if FILE is writable.
[[ -x FILE ]] # Checks if FILE is executable.
[[ f1 -nt f2 ]] # Checks if f1 is newer than f2.
[[ f1 -ot f2 ]] # Checks if f1 is older than f2.
[[ f1 -ef f2 ]] # Checks if f1 and f2 are the same file.
# example
touch ./test.txt
FILE="./test.txt"
if [[ -f $FILE ]]
then
echo "$FILE is a file"
else
echo "$FILE is NOT a file"
fi
if [[ -e "file.txt" ]]; then
echo "file exists"
fi
FOR loop
# FOR LOOP
NAMES="Brad Kevin Alice Mark"
for NAME in $NAMES
do
echo "Hello $NAME"
done
# FOR LOOP to rename files
touch 1.txt 2.txt 3.txt
FILES=$(ls *.txt)
NEW="new"
for FILE in $FILES
do
echo "Renaming $FILE to new-$FILE"
mV $FILE $NEW-$FILE
done
# C-like for loop
for ((i = 0 ; i < 100 ; i++)); do
echo $i
done
# Continue
for number in $(seq 1 3); do
if [[ $number == 2 ]]; then
continue;
fi
echo "$number"
done
# Break
for number in $(seq 1 3); do
if [[ $number == 2 ]]; then
# Skip entire rest of loop.
break;
fi
# This will only print 1
echo "$number"
done
Ranges
for i in {1..5}; do
echo "Welcome $i"
done
WHILE loop
# WHILE LOOP
COUNT=1
while [[ $COUNT -le 5 ]]
do
echo "Count is: $COUNT"
((COUNT++)) # Increment the count variable
done
Until
count=0
until [ $count -gt 10 ]; do
echo "$count"
((count++))
done
Forever
while true; do
# here is some code.
done
# shorthand
while :; do
# here is some code.
done
Reading lines
cat file.txt | while read line; do
echo $line
done
Function
# function without params
function sayHello() {
echo "Hello World"
}
sayHello
echo "This is my $(sayHello) function"
# function with params
function greet() {
echo "Hello $1, I am $2"
}
greet "Brad" "36"
# same
function greet() {
local NAME=$1
local AGE=$2
echo "Hello $NAME, I am $AGE"
}
greet "Brad" "36"
Return value
myfunc() {
local myresult='some value'
echo $myresult
}
result="$(myfunc)"
echo $result
Raise error
myfunc() {
return 1
}
if myfunc; then
echo "success"
else
echo "failure"
fi
Arguments
$1 … $9 # Parameter 1 ... 9
$0 # Filename of the script
$1 # First argument
${10} # Positional parameter 10
$# # Number of arguments
$$ # Process id (PID) of the shell
$! # PID of last background task
$? # Exit status of last task
$* # All arguments
$@ # All arguments, starting from first
$- # Current options
$_ # Last argument of the previous command
function greet() {
echo $0 # ./script.sh (name of the script)
echo $1 # Brad (parameter 1)
echo Hello $1, I am $2 # Hello Brad, I am 36
echo ${1} # Brad (positional parameter 1)
echo $* # Brad 36 (all arguments)
echo $@ # Brad 36 (all arguments starting from first)
echo $9 # ""
echo $# # 2 (number of arguments)
echo $$ # 98438 (process id of the shell)
echo $- # hB (current options)
echo $_ # hB (last argument of the previous command)
}
greet "Brad" "36"
CREATE FOLDER AND WRITE TO A FILE
# CREATE FOLDER AND WRITE TO A FILE
mkdir hello
touch "hello/world. txt"
echo "Hello World" >> "hello/world.txt"
echo "Created hello/world.txt"
Numeric calculations
a=1
echo $((a + 200))
Randomize
echo $(($RANDOM%200)) # Random number 0..199
Subshell Use round braces to run a command in separate shell
(cd ..; echo $PWD) # /Users/sherb/Git
echo $PWD # /Users/sherb/Git/antonarbus.com
Redirection
python hello.py > output.txt # stdout to (file)
python hello.py >> output.txt # stdout to (file), append
python hello.py 2> error.log # stderr to (file)
python hello.py 2>&1 # stderr to stdout
python hello.py > /dev/null # stdout to (null)
python hello.py 2> /dev/null # stderr to (null)
python hello.py &> /dev/null # stdout and stderr to (null)
python hello.py < foo.txt # feed foo.txt to stdin for python
Error handling trap executes an action when a certain event occurs
traperr() {
echo "ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}"
}
set -o errtrace
trap traperr ERR
some_incorrect_code
# ERROR: ./script.sh at about 10
printf Supports format specifiers (e.g., %s for strings, %d for integers), allowing for more complex text formatting Requires format strings, so it's slightly more complex to use By default, echo adds a newline at the end of its output, but printf does not
printf "Hello, %s!\n" "World"
printf "Hello %s, I'm %s" Sven Olga # => "Hello Sven, I'm Olga
printf "1 + 1 = %d" 2 # => "1 + 1 = 2"
printf "Print a float: %f" 2 # => "Print a float: 2.000000"
Ping
if ping -c 1 google.com; then
echo "It appears you have a working internet connection"
fi
Grep (search in text) grep stands for Global Regular Expression Print grep searches for text patterns within files or input streams
# -i: Case-insensitive search
grep -i "pattern" file.txt
# -r or -R: Recursive search in directories
grep -r "pattern" /path/to/directory
# -l: Only lists file names with matches, not the matching lines
grep -l "pattern" *.txt
# -v: Invert match; shows lines that do not contain the pattern.
grep -v "pattern" file.txt
# -c: Counts the number of matches per file.
grep -c "pattern" file.txt
# -n: Shows line numbers for each matching line.
grep -n "pattern" file.txt
# -q: Quiet mode; suppresses output, sets exit status only.
grep -q "pattern" file.txt && echo "Found" || echo "Not found"
# example
if grep -q 'foo' ~/.bash_history; then
echo "You appear to have typed 'foo' in the past"
fi
Backslash escapes Escape these special characters with \ ! " # & ' ( ) , ; < > [ | \ ] ^ { } ` $ * ? Multi-line text
# Printing Multi-line Text
cat <<EOF
Welcome to the Script!
This is a multi-line message.
EOF
# Redirecting Input to a Command
mysql -u user -p database <<EOF
SELECT * FROM users;
EOF
# Creating Configuration Files on the Fly
cat <<EOF > config.conf
[Settings]
theme=dark
EOF
# Save Multi-line Text in variable
message=$(cat <<EOF
This is a
multi-line string
stored in a variable.
EOF
)
echo "$message"
Pipe (connecting commands) Pipe sign (|) connects the output of one command to the input of another Piping allows to chain commands together to process data efficiently
# Lists files in long format is piped into grep
# Which shows only files with a .txt extension
ls -l | grep ".txt"
Useful shortcuts Git push cd ~/Git/antonarbus.com go into folder git add . && git commit -m 'xxx' git add, commit git push git push Deploy Anton Arbus on server ssh sherb@35.217.12.143 connect cd /var/www/html/antonarbus.com go to this web page folder npm i update packages npm run build pm2 restart app restart server pm2 stop app stop server pm2 delete app delete server pm2 start "npm run start" --name app --watch start app in watch mode Send archive to Anton Arbus cd ~/Git/antonarbus.com go into folder rm -r .next remove existing build folder npm run build build production folder tar -czf archive.tar.gz .next package.json next.config.js public compress build folder scp -r ~/Git/antonarbus.com/archive.tar.gz sherb@35.209.92.93:/var/www/html/antonarbus.com/ copy build archive from Win to server ssh sherb@35.217.12.143 connect cd /var/www/html/antonarbus.com go to this web page folder rm -r /var/www/html/antonarbus.com/.next remove existing build folder tar -xf archive.tar.gz extract archive Restart server via PM2 pm2 start "npm run start" --name app --watch start app in watch mode pm2 restart app restart server pm2 stop app stop server pm2 delete app delete server