Learning Linux Shell

5 minute read

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: backslash

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

Tags:

Categories:

Updated: