Learning Linux Shell
Check if a direcotry exists
dir="$HOME/perf"
if [ -d "$dir" ]; then
echo "direcotry $dir exists"
fi
[ -d "$dir" ] && echo "Directory $dir exists"
if [ ! -d "$dir" ]; then
echo "Directory $dir does not exist"
fi
[ ! -d "$dir" ] && echo "Directory $dir does not exist"
[[ -d $dir ]] && echo "Directory $dir exists" || echo "Directory $dir does not exist"
Get md5sum from its output
file=perfboot.yaml
md5=($(md5sum $file))
echo $md5 # a4659e0aae8fb5e90f978b3382029ab9
md5=$(md5sum $file)
echo ${md5% *} # a4659e0aae8fb5e90f978b3382029ab9
Remove suffix
file=trace-cmd.tar.bz2
echo "${file%.*}" # trace-cmd.tar
echo "${file%%.*}" # trace-cmd
Get filename from URL
PKG_SOURCE_URL="https://github.com/rostedt/trace-cmd/archive/trace-cmd-v1.1.1.tar.gz"
echo ${PKG_SOURCE_URL#*/} # /github.com/rostedt/trace-cmd/archive/trace-cmd-v1.1.1.tar.gz
echo ${PKG_SOURCE_URL##*/} # trace-cmd-v1.1.1.tar.gz
Variable name starts with ‘ANDROID_’
echo ${!ANDROID*} # ANDROID_HOME ANDROID_NDK_HOME
echo ${!ANDROID@} # ANDROID_HOME ANDROID_NDK_HOME
Case statement
item='cucumber'
case $item in
'cucumber')
echo "It's vegetables"
;;
'apple' | 'orange')
echo "It's fruit, I like it"
;;
*)
echo "I don't know that"
;;
esac
Add/remove item from array
arr=("This" "is" "an")
echo "${#arr[@]}" # array length is 3
arr+=( "example") # Note the space here
echo "${#arr[@]}" # array length is 4
for a in "${arr[@]}"
do
echo $a
arr=("${arr[@]:1}") # remove the first item
done
echo "${#arr[@]}" # array length is 4
Check if there is nothing to commit
if [ -z "$(git status --porcelain)" ]; then
echo "nothing to commit"
fi
Break line in csv file into variables
while read line
do
var1=$(echo $line | cut -d ',' -f1)
echo $var1
var2=$(echo $line | cut -d ',' -f2)
echo $var2
done < test.csv
grep with regex
# search for line end with foo
grep 'foo$' -n file
# search for line start with bar
grep '^bar' -n file
# search for line with only one word
grep '^foo$' -n file
# match zero or more white spaces
grep 'bar[ ]*$' -n file
# use variable in grep, note the double quotes
foo=bar
grep "$foo[ ]*$" -n file
Exclude a package from build
Here is an Android mk file used for build packages to the target system:
When removing a package, beware of these 4 situations:
- Remove package like
LineageParts
with backslash at the end, just remove this line is OK.package=LineageParts sed -i "/[ \t]*$package[ \t]*\\\/d" vendor/lineage/config/common.mk
- Remove pacakge like
Profiles
with only package name, the backslash in line 127 also needs to be removed.package=Profiles sed -i "/[ \t]*\\\\$/{N; s/[ \t]*\\\\\\n[ \t]*$package$//}" vendor/lineage/config/common.mk
- Remove package which has only one module in variable, the variable also needs
to be removed.
package=Exchange2 sed -i "/[ \t]*\\\\$/{N; s/[ \t]*\\\\\\n[ \t]*$package$//}" vendor/lineage/config/common.mk sed -i "/^PRODUCT_PACKAGES +=$/d" vendor/lineage/config/common.mk
Format disk
sudo parted -a optimal -s /dev/sdb mklabel gpt
sudo parted -s /dev/sdb -- mkpart primary ext4 1 -1
sudo mkfs.ext4 /dev/sdb1
# mount at boot via fstab
echo "UUID=$(blkid /dev/sdb1 -o value -s UUID) /opt/user ext4 defaults 0 2" | sudo tee -a /etc/fstab > /dev/null
Get list of user installed packages
# Using apt-mark
comm -23 <(apt-mark showmanual | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)
# Using aptitude
comm -23 <(aptitude search '~i !~M' -F '%p' | sed "s/ *$//" | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)
# Install on the new machine
# save above results to user-installed-packages
sed 's/$/\tinstall/' user-installed-packages >uip
sudo dpkg --set-selections < uip
sudo apt-get dselect-upgrade
split large file
split -b 2G example.tar.bz2 example.tar.bz2.part
cat example.tar.bz2.part* >example.tar.bz2
make archive
# exclude directory, .git and file
tar --exclude=".repo" --exclude-vcs --exclude='build.sh' -cvf /tmp/archive.tar ~/aosp
# remove leading directory
tar -xf archive.tar --strip-components=1
generate patch between two tags
git diff tag1 tag2 -- > very-big.patch
remove vendor project from manifest
sed -i "/hardware\/intel/ {s/^/<\!--/; s/$/-->/}" .repo/manifests/default.xml
sed -i "/hardware\/intel/ {s/<project/<\!-- project/; s/$/-->/}" .repo/manifests/default.xml
add projects with different revisions to manifest
rev="lineage-15.1"
sed -i "/<repo-hooks/ i \ <project path=\"device/brcm/rpi3\" name=\"lineage-rpi/android_device_brcm_rpi3\" revision=\"${rev}\" \/>\n\
\ <project path=\"kernel/brcm/rpi3\" name=\"lineage-rpi/android_kernel_brcm_rpi3\" revision=\"${rev}\" \/>\n\
\ <project path=\"vendor/brcm\" name=\"lineage-rpi/proprietary_vendor_brcm\" revision=\"${rev}\" \/>\n" .repo/manifests/default.xml
Extract audio with ffmpeg
ffmpeg -i input-video.avi -vn -acodec copy output-audio.aac
ffmpeg -i video.mp4 -f mp3 -ab 192000 -vn music.mp3
Extract audio from bunch of video files
video_dir="~/friends"
# handle filename with spaces
find ${video_dir} -type f -name '*.mkv' -exec sh -c '
for file do
tmp=${file%.*}
season=${tmp%/*}
mp3_dir="~/friends/audio/${season#*friends/}"
if [ ! -d "${mp3_dir}" ]; then
mkdir -p "${mp3_dir}"
fi
mp3_file="${tmp##*/}.mp3"
ffmpeg -i "${file}" -f mp3 -ab 192000 -vn "${mp3_dir}/${mp3_file}"
done
' sh {} +
Trim audio files
ffmpeg -i input.mp3 -ss 00:17:00 -acodec copy trim.mp3
ffmpeg -i input.mp3 -ss 00:00:00 -to 00:24:30 -c copy trim.mp3
parent pid
echo $PPID
cat /proc/$PPID/comm
cat /proc/$PPID/cmdline
install specific version of python package
pip install --user wlauto==3.1.1
pip install --user -v wlauto==3.1.1
Simulate low memory on android devices
# The level can be one of the following:
# HIDDEN
# RUNNING_MODERATE
# BACKGROUND
# RUNNING_LOW
# MODERATE
# RUNNING_CRITICAL
# COMPLETE
am send-trim-memory <pid> <level>
tty stuff
# Get the name of the current terminal
# /dev/pts/28
tty
# Get all logged session
who
w
# show all the terminal session
ps o tty
generate tombstone for specified pid
debuggerd <pid>
generate ps tree with dot
temp_file=`mktemp`
dot_file="pstree.dot"
ps -eo pid,ppid | grep -v 'PPID' >> ${temp_file}
echo "digraph {" > ${dot_file}
while read -r line;
do
echo " ${line##* } -> ${line%% *};" >> ${dot_file}
done < <(cat ${temp_file})
echo "}" >> ${dot_file}
dot -Tsvg ${dot_file} > pstree.svg
String length
string=123456790abcd
echo ${#string}
Line counting
# for git repo
git ls-files | xargs wc -l
# for non-vcs directory
wc -l $(find . -type f | egrep "\.(h|cc|c|cpp)")
Config java version
sudo update-alternatives --config java
Change display resolution
rm .config/unity-monitors.xml
xrandr -d :0 --output $(xrandr -d :0 -q | grep primary | cut -d ' ' -f1) --mode 1920x1080
# Run above command or add to ~/.xprofile
xrandr --output HDMI-1 --mode 1920x1080 --rate 60
Replace white space with dot in file name
rename 's/ /./g' *
Rotate video
ffmpeg -i IMG_5263.TRIM.MOV -metadata:s:v rotate="90" -codec copy IMG_5263.MOV
Disk backup
rsync -rvlpogt /media/fdbai/ugreen/media/ /media/fdbai/Backup/media/
Resources
- Shell Parameter Expansion
- Difference between single and double quotes in Bash
- How can you combine all lines that end with a backslash character?
- How can you combine all lines that end with a backslash character?
- Debugger and code formatter for sed scripts
- Generating list of manually installed packages and querying individual packages
- Find all user-installed packages
- using ffmpeg to extract audio from video files
- Looping through files with spaces in the names?
- Why is using a shell loop to process text considered bad practice?
- Why is looping over find’s output bad practice?
- Setting Resolution