Po-Yi Chou

undergraduate in EECS in NCTU


Project maintained by poyichou Hosted on GitHub Pages — Theme by mattgraham

Home Notes Scripts Code Contact Blog

Scripts

analysis.sh

Find first 5 largest file under your working directory
#!/bin/sh
#first 5 largest file under your directory
ls -R -A -l | grep '^[-d]' | sort -k 5 -n | awk '{print $5, $9} /^-/ {fn+=1} /^-/ {fs+=$5} /^d/ {dn+=1} END {print "7b: "fn "\n" "6a: "fs "\n" "8c: "dn}' | tail -n 8 | sort -n -r | awk '{print NR ":" $1, $2}' | sed -e 's/[6-8]://g' -e 's/8c:/Dir num:/g' -e 's/7b:/File num:/g' -e 's/6a:/Total:/g'

    

dialog_web_browser.sh

A simple dialog style web browser
#!/bin/sh -x

exec 2> ~/.mybrowser/error
quit=1
cancel=0
page="google.com"
skipcurrent=0
pagestate=0
inputmsg="type command or url"
ipage=0
index=1
total=1
url="https://google.com"
#test
if [ $( ls ~ | grep '^Downloads$' ) != "Downloads" ]; then
	mkdir ~/Downloads
fi
if [ $( ls -a ~ | grep '^\.mybrowser$' ) != ".mybrowser" ]; then
	mkdir ~/.mybrowser
fi
#insert help page
echo "URL ==> go to the source code" >~/.mybrowser/help
echo "/S ==> show me the source code" >>~/.mybrowser/help
echo "/L ==> select a link to go" >>~/.mybrowser/help
echo "/D ==> select a link to download" >>~/.mybrowser/help
echo "/H ==> help page" >>~/.mybrowser/help
echo '!${cmd} ==> execute the shell cmd' >>~/.mybrowser/help
#insert userterms
echo "Are you agree the userterms??" >~/.mybrowser/userterm
#insert error code
echo "Invalid Input" >~/.mybrowser/error
echo "Try /H for help messages." >>~/.mybrowser/error
#insert first page
echo "https://google.com" >~/.mybrowser/iPages
dialog --title "terms" --yesno "$(cat ~/.mybrowser/userterm)" 1000 100
yn=$?

#disagree
if [ $yn != 0  ]; then
	quit="2"
	dialog --title "Apology" --msgbox "Sorry, You cant't use Browser, if you don't agree the user terms" 1000 100
fi

while [ "$quit" != "2" ]
do
	cancel=0
	if [ $skipcurrent != "1" ] && [ $pagestate = 0 ]; then
		#homepage
		dialog --title "Browser" --msgbox "$(w3m -dump $page)" 1000 100
	elif [ $skipcurrent != "1" ] && [ $pagestate = 1 ]; then
		#curl
		dialog --title "browser" --msgbox "$(curl -s -L $page)" 1000 100
		pagestate=0
	elif [ $skipcurrent != "1" ] && [ $pagestate = 2 ]; then
		#manual
		dialog --title "help" --msgbox "`cat "$page"`" 1000 100
	elif [ $skipcurrent != "1" ] && [ $pagestate = 3 ]; then
		dialog --title "browser" --msgbox "$page" 1000 100
	fi
	dialog --title "Browser" --inputbox "$page" 8 100 2>~/.mybrowser/command
	#quit
	if [ $? = 1 ]; then
		quit="2"
		cancel="1"
	#cancel
	elif [ $? = 255 ]; then
		cancel="1"
	fi
	skipcurrent=0
	
	com=`cat ~/.mybrowser/command`
	if [ "$quit" != "2" ] && [ "$cancel" != "1" ] && [ "$com" = "/S" ]; then
			pagestate=1
                        page=$url
#			dialog --title "browser" --msgbox "$(curl -s -L $page)" 1000 100
	elif [ "$quit" != "2" ] && [ "$cancel" != "1" ] && [ "$com" = "last" ]; then
		if [ $index -ge 2 ]; then
			index=$(expr $index - 1)
			page=$(awk 'NR == '"$index"' {print $0}' ~/.mybrowser/iPages)
			pagestate=0
		else
			dialog --msgbox "no last page QQ" 200 100
		fi
	elif [ "$quit" != "2" ] && [ "$cancel" != "1" ] && [ "$com" = "next" ]; then
		if [ $index -lt $total ]; then
			index=$(expr $index + 1)
			page=$(awk 'NR == '"$index"' {print $0}' ~/.mybrowser/iPages)
			pagestate=0
		else
			dialog --msgbox "no next page QQ" 200 100
		fi
	
	elif [ "$quit" != "2" ] && [ "$cancel" != "1" ] && [ "$com" = "/L" ]; then
		curl -s -L $url | grep '<a.*href' | sed -e 's/.*<a.*href="//g' -e 's/".*>.*//g' -e 's/[[:space:]]//g' -e 's~^\/~'"$url"'\/~g' | awk '/tps:\/\// {print NR, $0} /tp:\/\// {print NR, $0} /[^: ]/ {print NR, var "\/"  $0}' var="$url"| sed 's/.*http.*http.*//g' | grep '[1-9]'  >~/.mybrowser/Link
		if [ "$cancel" != "1" ]; then
			dialog --title "browser" --menu "Links" 1000 100 100 `cat ~/.mybrowser/Link` 2>~/.mybrowser/Choice
		
			#cancel
			if [ $? != 0 ]; then
				cancel="1"
			fi
			
			if [ "$cancel" != "1" ]; then
				catchoice=`cat ~/.mybrowser/Choice`
				churl=$(grep ^$(cat ~/.mybrowser/Choice | sed 's/\$//g')\  ~/.mybrowser/Link | sed 's/^'"$catchoice"'\ //g')
				pagestate=0
				page=$churl
				url=$churl
				if [ $index -eq 1 ]; then
					sed -n '1p' ~/.mybrowser/iPages >~/.mybrowser/tmptmp
				else
					sed -n '1,'"$index"'p' ~/.mybrowser/iPages >~/.mybrowser/tmptmp
				fi
				cat ~/.mybrowser/tmptmp >~/.mybrowser/iPages
				echo $churl >>~/.mybrowser/iPages
				index=$(expr $index + 1)
				total=$index
			fi
		fi
	elif [ "$quit" != "2" ] && [ "$cancel" != "1" ] && [ "$com" = "/H"  ]; then
		dialog --title "Help" --msgbox "`cat ~/.mybrowser/help`" 200 100
	elif [ "$quit" != "2" ] && [ "$cancel" != "1" ] && [ "$com" = "/D" ]; then
		if [ "$cancel" != "1" ]; then
			curl -s -L $url | grep '<a.*href' | sed -e 's/.*<a.*href="//g' -e 's/".*>.*//g' -e 's/[[:space:]]//g' -e 's~^\/~'"$url"'\/~g' | awk '/tps:\/\// {print NR, $0} /tp:\/\// {print NR, $0} /[^: ]/ {print NR, var "\/"  $0}' var="$url" | sed 's/.*http.*http.*//g' | grep '[1-9]' >~/.mybrowser/Link
		fi
		while [ "$cancel" != "1" ]
		do
			dialog --title "browser" --menu "Download:" 1000 100 100 `cat ~/.mybrowser/Link` 2>~/.mybrowser/Choice
			
			#cancel
			if [ $? != 0 ]; then
				cancel="1"
			fi
			if [ "$cancel" != "1" ]; then
				catchoice=`cat ~/.mybrowser/Choice`
				churl=$(grep ^$(cat ~/.mybrowser/Choice | sed 's/\$//g')\  ~/.mybrowser/Link | sed 's/^'"$catchoice"'\ //g')
				fetch -o ~/Downloads "$churl" 2>~/.mybrowser/Result
#				pagestate=3
#				page=`cat ~/.mybrowser/Result`
				cancel="1"
#				dialog --title "browser" --msgbox "$(cat ~/.mybrowser/Result)" 1000 100
			fi
		done
#	elif [ "$quit" != "2" ] && [ "$com" = "Q" ]; then
#		quit="2"
#		dialog --title "browser" --msgbox "Stop!!" 200 100
	elif [ "$quit" != "2" ] && [ "$cancel" != "1" ] && [ "$com" = "/B" ]; then
		j="1"
		while [ "$cancel" != "1" ] && [ $j != "2" ]
		do
			#delete blank row
			cat ~/.mybrowser/Bookmarks | grep '[a-zA-z0-9]' >~/.mybrowser/tmp
			cat ~/.mybrowser/tmp >~/.mybrowser/Bookmarks
			dialog --title "browser" --menu "Bookmarks:" 1000 100 100 1 "Add Bookmarks" 2 "Delete Bookmarks" $(cat ~/.mybrowser/Bookmarks | awk '{print NR+2, $0}') 2>~/.mybrowser/Mark
			
			#cancel
			if [ $? != 0 ]; then
				cancel="1"
			fi
			if [ "$cancel" != "1" ]; then
				catmark=`cat ~/.mybrowser/Mark`
			fi
#			mark==$(grep ^$(cat ~/.mybrowser/Mark | sed 's/\$//g')\  ~/.mybrowser/Bookmarks | sed 's/^'"$catmark"'\ //g')
			if [ "$cancel" != "1" ] && [ $catmark = "1" ]; then
				dialog --title "Add Bookmarks:" --inputbox "type url:" 8 100 2>~/.mybrowser/AddBook
				
				#cancel
				if [ $? != 0 ]; then
					cancel="1"
				fi

				if [ "$cancel" != "1" ]; then
					if [ $(sed 's/nasa\.cs\.nctu\.edu\.tw/iamurl/g' ~/.mybrowser/AddBook) != "iamurl" ]; then
						while [ "$cancel" != "1" ] && [ $(sed -e 's/^http:\/\/[A-Za-z0-9][A-Za-z0-9]*\.[A-Za-z0-9].*/iamurl/g' ~/.mybrowser/AddBook) != "iamurl" ] && [ $(sed -e 's/^https:\/\/[A-Za-z0-9][A-Za-z0-9]*\.[A-Za-z0-9].*/iamurl/g' ~/.mybrowser/AddBook) != "iamurl" ]
						do
							dialog --title "Add Bookmarks:" --inputbox "that doesn't url, type url again:" 8 100 2>~/.mybrowser/AddBook
							#cancel
							if [ $? != 0 ]; then
								cancel="1"
							fi
						done
						if [ "$cancel" != "1" ]; then
							cat ~/.mybrowser/AddBook >>~/.mybrowser/Bookmarks
							echo $'\n'>>~/.mybrowser/Bookmarks
							dialog --title "Add Bookmarks:" --msgbox "Added!!" 8 100
							
							#cancel
							if [ $? != 0 ]; then
								cancel="1"
							fi
						fi
					fi
				fi
			elif [ "$cancel" != "1" ] && [ $catmark = "2" ]; then
				dialog --title "Delete Bookmarks:" --menu "choose one" 1000 100 100 $(cat ~/.mybrowser/Bookmarks | awk '{print NR, $0}') 2>~/.mybrowser/DeleteBook
				
				#cancel
				if [ $? != 0 ]; then
					cancel="1"
				fi

				if [ "$cancel" != "1" ]; then
					catdeletebook=`cat ~/.mybrowser/DeleteBook`
					chbook=$(awk ' NR == '"$catdeletebook"'  {print $0} ' ~/.mybrowser/Bookmarks )
					cat ~/.mybrowser/Bookmarks | grep -v $chbook >~/.mybrowser/tmp 
					cat ~/.mybrowser/tmp >~/.mybrowser/Bookmarks
					dialog --title "Delete Bookmarks:" --msgbox "Deleted!!" 8 100
					
					#cancel
					if [ $? != 0 ]; then
						cancel="1"
					fi
				fi
			elif [ "$cancel" != "1" ] && [ $catmark -ge 3 ]; then
				chbook=$(awk ' NR == '"$catmark -2"'  {print $0} ' ~/.mybrowser/Bookmarks )
#				dialog --title "browser" --msgbox "$(w3m -dump "$chbook")" 200 100
				#cancel
				if [ $? != 0 ]; then
					cancel="1"
				fi
				if [ "$cancel" != "1" ]; then
					pagestate=0
					page=$chbook
					url=$chbook
					j="2"
					if [ $index -eq 1 ]; then
						sed -n '1p' ~/.mybrowser/iPages >~/.mybrowser/tmptmp
					else
						sed -n '1,'"$index"'p' ~/.mybrowser/iPages >~/.mybrowser/tmptmp
					fi
					cat ~/.mybrowser/tmptmp >~/.mybrowser/iPages
					echo $chbook >>~/.mybrowser/iPages
					index=$(expr $index + 1)
					total=$index
				fi
			else
				j="2"
			fi
		done

	#type url
	elif [ "$quit" != "2" ] && [ $(echo $com | sed -e 's/^http:\/\/[A-Za-z0-9][A-Za-z0-9]*\.[A-Za-z0-9].*/iamurl/g') = "iamurl" ] || [ $(echo $com | sed -e 's/^https:\/\/[A-Za-z0-9][A-Za-z0-9]*\.[A-Za-z0-9].*/iamurl/g') = "iamurl" ] || [ $com = "nasa.cs.nctu.edu.tw/sap" ]; then
		url=$com
		page=$com
		inputmsg=$com
		if [ $index -eq 1 ]; then
			sed -n '1p' ~/.mybrowser/iPages >~/.mybrowser/tmptmp
		else
			sed '1,'"$index"'p' ~/.mybrowser/iPages >~/.mybrowser/tmptmp
		fi
		cat ~/.mybrowser/tmptmp >~/.mybrowser/iPages
		echo $com >>~/.mybrowser/iPages
		index=$(expr $index + 1)
		total=$index
	#type wrong command
	elif [ "$quit" != "2" ] && [ "$cancel" != "1" && $( echo $com | sed -e 's/^\/.*/wrongcammand/g' ) != "wrongcammand" ]; then
		dialog --title "Invalid input" --msgbox "`echo "Invalid Input";echo "Try /H for help messages."`" 1000 100
		#cancel
		if [ $? != 0 ]; then
			cancel="1"
		fi
		skipcurrent="1"
	elif [ "$quit" != "2" ] && [ $( echo $com | sed -e 's/^!.*/0/g' ) = 0 ]; then
		shellcom=$( echo $com | sed -e 's/^!//g' )
		$shellcom >shellcomResult
		dialog --title "shell command" --msgbox "`cat shellcomResult`" 200 100
	elif [ "$quit" != "2" ]; then
		skipcurrent="1"
		dialog --title "Invalid input" --msgbox "`echo "Invalid Input";echo "Try /H for help messages."`" 1000 100
	fi
done 

    

arch-install.sh

Install Arch Linux for amd64 machine with UEFI (Virtualbox issue handled)
#!/bin/sh

# Note:
#     Install archlinux on an "amd64" machine with "UEFI" by default.
#     To check whether your host running uefi or not, check /sys/firmware/efi exist or not.
#     Network connection and root privilege are required.
#     For those who are not using Virtualbox, comment out the "For virtualbox (efi)" block.


timedatectl set-ntp true

efi_gpt_partition() {
    # 
    # ============ GPT/UEFI Partition Table ==============
    # /boot     /dev/sda1 	EFI System Partition    511 M
    # [SWAP]    /dev/sda2 	Linux swap              1.5 G
    # /         /dev/sda3 	Linux                   rest 
    # ====================================================
    # 
    # both 
    #   parted /dev/sda --script set 1 esp on
    #   parted /dev/sda --script set 1 boot on
    # would work
    parted /dev/sda --script \
        mklabel gpt \
        mkpart ESP fat32 1MiB 512MiB \
        set 1 boot on \
        mkpart primary linux-swap 512MiB 2GiB \
        mkpart primary ext4 2GiB 100%
    mkfs.fat -F32 /dev/sda1
    mkfs.ext4 /dev/sda3
    # initialize partition for swap
    mkswap /dev/sda2
    swapon /dev/sda2
    
    # mount
    mount /dev/sda3 /mnt
    mkdir -p /mnt/boot/EFI
    mount /dev/sda1 /mnt/boot/EFI
}

bios_mbr_partition() {
    # ============ MBR/BIOS Partition Table ==============
    # [SWAP]    /dev/sda1 	Linux swap              1   G
    # /         /dev/sda2 	Linux                   rest 
    # ====================================================
    parted /dev/sda --script \
        mklabel msdos \
        mkpart primary linux-swap 1MiB 1GiB \
        mkpart primary ext4 1GiB 100% \
        set 2 boot on
    mkfs.ext4 /dev/sda2
    # initialize partition for swap
    mkswap /dev/sda1
    swapon /dev/sda1
    
    # mount
    mount /dev/sda2 /mnt
}

efi_gpt_partition
# different choice
#bios_mbr_partition

## select mirrors
#cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup
## extract all the servers of Taiwan for old version of mirrorlist
#awk '
#/^## Taiwan$/ { f=1; print $0; next }
#f==0 { next }
#/^$/ { exit }
#{ print $0; f=0 }' /etc/pacman.d/mirrorlist.backup > /etc/pacman.d/mirrorlist
## uncomment every mirror
#sed -i 's/^#Server/Server/' /etc/pacman.d/mirrorlist
## only output the 6 fastest mirrors
##rankmirrors -n 6 /etc/pacman.d/mirrorlist.backup > /etc/pacman.d/mirrorlist

# Install the base packages
pacman -Sy --noconfirm archlinux-keyring
pacstrap /mnt base base-devel

# genfstab
genfstab -U /mnt >> /mnt/etc/fstab

# create a script to use afterward
echo "#!/bin/bash

echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen
locale-gen
echo 'LANG=en_US.UTF-8' > /etc/locale.conf

# time zone
ln -sf /usr/share/zoneinfo/Asia/Taipei /etc/localtime
hwclock --systohc --utc

echo arch > /etc/hostname
echo '127.0.0.1	localhost.localdomain	localhost	 arch
::1	localhost.localdomain	localhost	 arch' >> /etc/hosts

# Initramfs
pacman -S --noconfirm linux linux-firmware
mkinitcpio -p linux

# boot loader (grub)
pacman -S --noconfirm grub efibootmgr
grub-install /dev/sda --target=x86_64-efi --bootloader-id=grub_uefi --recheck
# For MBR/BIOS
#grub-install /dev/sda
# For intel CPU
pacman -S --noconfirm intel-ucode
# For those who want to have dual OS with win10 installed
#pacman -S --noconfirm os-prober
#os-prober
# Generate the main configuration file
grub-mkconfig -o /boot/grub/grub.cfg

# create /home
mkdir /home
echo '/home created'

# Previous problem solution
# For virtualbox (efi) (Remember to enable EFI in Machine->System->Extended Features)
# Method1
#mkdir/boot/EFI/BOOT
#cp /boot/EFI/GRUB/grubx64.efi /boot/EFI/BOOT/BOOTX64.EFI
# Method2
#echo 'fs0:\EFI\grub\grubx64.efi' > /boot/startup.nsh

# Pre-installation
pacman -Syu --noconfirm --needed bash-completion gcc gdb vim openssh git valgrind dialog wget curl tmux zip unzip sudo wpa_supplicant netctl dhcpcd man-db man-pages texinfo

# Dhcpcd (Network)
systemctl enable dhcpcd.service

# ============================================================================
# ==================== Remember to change it after reboot ====================
# ============================================================================
# set defualt password
echo -e 'root\nroot' | passwd root
" > /mnt/archsetup.sh
# chroot
arch-chroot /mnt /bin/bash /archsetup.sh
rm -f /mnt/archsetup.sh

umount -R /mnt
sync
poweroff

# Remember to remove the installation media before booting again

    

http_download_server.py

A simple HTTP download server for file sharing
'''
download FILENAME whenever GET
'''
try:
    import http.server as BaseHTTPServer  # Python 3.x
except ImportError:
    import BaseHTTPServer  # Python 2.x
import os
import shutil
import sys

if len(sys.argv) < 2:
    print('usage: python {} <share file> [port]'.format(__file__))
    exit()

FILEPATH = os.path.abspath(sys.argv[1])
FILENAME = os.path.basename(FILEPATH)

if os.path.isdir(FILEPATH): # folder, send zipped file instead
    import zipfile
    ZIP_PATH = '/tmp/{}.zip'.format(FILENAME)
    with zipfile.ZipFile(ZIP_PATH, 'w', zipfile.ZIP_DEFLATED) as zf:
        for root, dirs, files in os.walk(FILEPATH):
            for file_name in files:
                zf.write(os.path.join(root, file_name), '{}/{}'.format(FILENAME, file_name))

    FILENAME = os.path.basename(ZIP_PATH)
    FILEPATH = ZIP_PATH



PORT = 7000 if len(sys.argv) < 3 else int(sys.argv[2])

class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        with open(FILEPATH, 'rb') as f:
            self.send_response(200)
            self.send_header("Content-Type", 'application/zip')
            self.send_header("Content-Disposition", 'filename="{}"'.format(FILENAME.encode("utf-8").decode("latin1")))
            self.end_headers()
            shutil.copyfileobj(f, self.wfile)

def test(HandlerClass=HTTPRequestHandler,
         ServerClass=BaseHTTPServer.HTTPServer,
         protocol="HTTP/1.0"):
    server_address = ('', PORT)

    HandlerClass.protocol_version = protocol
    httpd = BaseHTTPServer.HTTPServer(server_address, HandlerClass)

    sa = httpd.socket.getsockname()
    print("Serving HTTP on {0[0]} port {0[1]} ... {1}".format(sa, FILENAME))
    try:
        httpd.serve_forever()
    except KeyboardInterrupt as e:
        pass

if __name__ == '__main__':
    test()

    

multi_line_progress.sh

A simple test for printing multiple progress bar
#!/bin/sh
# Just a simple test for printing multiple progress bar

ECHO() {
    echo $@
    [ -z "$up" ] && up=1 || up=$((up+1)) # set lines to move up afterwards
}
while sleep 1; do
    [ -n "$up" ] && tput cuu $up && up='' # move up $up lines
    ECHO "line$((i=i+1))"
    ECHO "line$((i=i+1))"
    ECHO "line$((i=i+1))"
    ECHO "line$((i=i+1))"
done