Array in Bash
string="0123456789" # create a string of 10 characters
array=(0 1 2 3 4 5 6 7 8 9) # create an indexed array of 10 elements
declare -A hash
hash=([one]=1 [two]=2 [three]=3) # create an associative array of 3 elements
echo "string length is: ${#string}" # length of string
echo "array length is: ${#array[@]}" # length of array using @ as the index
echo "array length is: ${#array[*]}" # length of array using * as the index
echo "hash length is: ${#hash[@]}" # length of array using @ as the index
echo "hash length is: ${#hash[*]}" # length of array using * as the index
Special characters in Bash
Special Variable Variable Details
- $1 to $n : $1 is the first arguments, $2 is second argument till $n n’th arguments.
From 10’th argument, you must need to inclose them in braces like ${10}, ${11} and so on
- $0 : The name of script itself
- $$ : Process id of current shell
- $* : Values of all the arguments. All agruments are double quoted
- $# : Total number of arguments passed to script
- $@ : Values of all the arguments
- $? : Exit status id of last command
- $! : Process id of last command
Init a git repository
# Git global setup
git config --global user.name "myname"
git config --global user.email "myemail@domain.local"
#Create a new repository
git clone git@gitlab.domain.net:it/diskusagereports.git
cd diskusagereports
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master
# Push an existing folder
cd existing_folder
git init
git remote add origin git@gitlab.domain.net:it/diskusagereports.git
git add .
git commit -m "Initial commit"
git push -u origin master
# Push an existing Git repository
cd existing_repo
git remote rename origin old-origin
git remote add origin git@gitlab.domain.net:it/diskusagereports.git
git push -u origin --all
git push -u origin --tags
Retrieve just one file from a remote repository
git archive --format=tar --remote=git_url HEAD -- <file> | tar xf -
Git: make hotfix
# display branch info
git branch -v
#go in branch hotfix/xx
git checkout -b hotfix/xx
# commit change
git commit -am "ton message"
git status
# push hotfix
git push origin hotfix/xxx
# MAJ branch master
git pull master
# update submodule
git submodule update --init --remote
# init submodule with branch
git submodule add -b branchname git@bitbucket.org:dir/repo.git path_to_submodule
Annuler un commit après un push
# Annuler un commit, c'est finalement appliquer l'inverse de son diff !
# On peut rediriger le diff des commits à annuler vers la commande patch --reverse :)
git diff HEAD^ | patch --reverse
# Pour faire plus simple, il y a git revert !
# Par exemple pour annuler les trois derniers commits :
git revert HEAD~3..HEAD
# Ou pour annuler un commit en particulier :
git revert 444b1cff
# Il suffit alors de pousser proprement le commit obtenu sur le serveur.
Branch manipulation
# To list all local branches
git branch
# To list all remote branches
git branch -r
# To list all branches (local and remote)
git branch -a
# If you are on the branch you want to rename:
git branch -m new-name
# Delete the old-name remote branch and push the new-name local branch.
git push origin :old-name new-name
# Reset the upstream branch for the new-name local branch.
# Switch to the branch and then:
git push origin -u new-name
# Deleting a single local branch
git branch -d <branchname>
# If you are sure you want to delete an unmerged branch:
git branch -D <branch>
# To delete all merged local branches:
git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d
# DANGER! Only run these if you are sure you want to delete unmerged branches.
# delete all local unmerged branches
git branch --no-merged | egrep -v "(^\*|master|dev)" | xargs git branch -D
# delete all local branches (merged and unmerged).
git branch | egrep -v "(^\*|master|dev)" | xargs git branch -D
# Deleting non-existent tracking branches
git remote prune <remote> --dry-run
# Deleting a single remote branch
git push <remote> --delete <branch>
# To delete all merged remote branches:
git branch -r --merged | egrep -v "(^\*|master|dev)" | sed 's/origin\///' | xargs -n 1 git push origin --delete
Init a git repository
Init a git repository
Linux rename username
The really right way? Say you want to change user ‘peter’ to ‘paul’.
groupadd paul usermod -d /home/paul -m -g paul -l paul peter
list of file used by PID
lsof -a -p <PID>
# ls - l /proc/<PID>/fd
ps -aeo pid,pcpu,args --sort=-%cpu | head
Linux SiG Signal list of file used by PID
SIGHUP -HUP gracefully reloads the workers and the application
SIGTERM -TERM "brutally" reloads
SIGINT -INT and SIGQUIT -QUIT kills all the workers immediately
SIGUSR1 -USR1 prints statistics (stdout)
SIGUSR2 -USR2 prints worker status
SIGURG -URG restores a snapshot
SIGTSTP -TSTP pauses, suspends or resumes an instance
SIGWINCH -WINCH wakes up a worker blocked in a syscall
Remove all package marked as rc
$ dpkg --list |grep "^rc" | cut -d " " -f 3 | xargs sudo dpkg --purge
how-to-loop-through-file-names-returned-by-find
Execute process
once for each file
find . -name '*.txt' -exec process {} \;
If you have time, read through the rest to see several different ways and the problems with most of them.
The full answer:
The best way depends on what you want to do, but here are a few options. As long as no file or folder in the subtree has whitespace in its name, you can just loop over the files:
for i in $x; do # Not recommended, will break on whitespace
process "$i"
done
# Marginally better, cut out the temporary variable x:
for i in $(find -name \*.txt); do # Not recommended, will break on whitespace
process "$i"
done
#It is much better to glob when you can. White-space safe, for files in the current directory:
for i in *.txt; do # Whitespace-safe but not recursive.
process "$i"
done
# By enabling the globstar option, you can glob all matching files in this directory and all subdirectories:
# Make sure globstar is enabled
shopt -s globstar
for i in **/*.txt; do # Whitespace-safe and recursive
process "$i"
done
# IFS= makes sure it doesn't trim leading and trailing whitespace
# -r prevents interpretation of \ escapes.
while IFS= read -r line; do # Whitespace-safe EXCEPT newlines
process "$line"
done < filename
# read can be used safely in combination with find by setting the delimiter appropriately:
find . -name '*.txt' -print0 |
while IFS= read -r -d '' line; do
process "$line"
done
# For more complex searches, you will probably want to use find,
# either with its -exec option or with -print0 | xargs -0:
# execute `process` once for each file
find . -name \*.txt -exec process {} \;
# execute `process` once with all the files as arguments*:
find . -name \*.txt -exec process {} +
# using xargs*
find . -name \*.txt -print0 | xargs -0 process
# using xargs with arguments after each filename
# (implies one run per filename)
find . -name \*.txt -print0 | xargs -0 -I{} process {} argument
Rsync ssh script
#!/usr/bin/env bash
checkBinary() {
command -v "$1" >/dev/null 2>&1 || { echo >&2 "please install binary : $1. Aborting."; exit 1; }
}
checkBinary "rsync"
clear
STIME=$(date +"%X")
SOURCE_USER="appREMOTE"
SOURCE_HOST="app.mydomain.com"
SOURCE_DIR="/mnt/production/web/uploads/media/*"
DEST_DIR="/efs/media/"
rsync -avz \
--chown=1000:1000 \
-e "ssh -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-i /home/ubuntu/.ssh/id_rsa" \
${SOURCE_USER}@"${SOURCE_HOST}":"${SOURCE_DIR}" \
"${DEST_DIR1}"
printf "### Initiated at : %s\n" ${STIME}
printf "### Terminated at : %s\n" $(date +"%X")
exit 0
Benchmark script with strace
Now let’s remove all the packages marked as rc.
strace -o trace -c -Ttt ./scrip
# where:
# -c is to trace the time spent by cpu on specific call.
# -Ttt will tell you time in microseconds at time of each system call running.
# -o will save output in file "trace".
Compile script and crypt
apt install shc
# to see content of encrypt script :
env SHELLOPTS=verbose ./test
mount RAID LVM disk recovery
- boot sous linux live
- install mdadm : apt install mdadm
- RAID1 + LVM
- mdadm –detail –scan
- cat /proc/mdstat
- mdadm -A -R /dev/md/8 /dev/sdc8
- mdadm -S /dev/vg/lv
- lvdisplay
- mount /dev/lg/lv
HTTP load generator
Make ISO command line linux
# Install package
apt install genisoimage
mkisofs -allow-limited-size -l -J -r -iso-level 3 -o
# this command will generate bigger then 4GB ISO
Disabled SWAP on linux
> swapon --show
NAME TYPE SIZE USED PRIO
/dev/sda2 partition 4G 0B -1
> fallocate -l 1G /swapfile
> dd if=/dev/zero of=/swapfile bs=1024 count=1048576
> chmod 600 /swapfile
> mkswap /swapfile
> swapon /swapfile
> nano /etc/fstab
# Edit : /etc/fstab
/swapfile swap swap defaults 0 0
> swapon --show
NAME TYPE SIZE USED PRIO
/swapfile file 1024M 507.4M -1
Get detailled disk partitions
> findmnt -Do TARGET,SOURCE,USED,SIZE,OPTIONS
Flush DNS MacOSx
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
Openlens block update
sudo chmod -R 000 ~/Library/Application\ Support/Caches/open-lens-updater/pending