Create multiple directories at once mkdir

สั้น !!
ความน่ารักและมีประโยชน์ของ Bash ก็คือบางอย่างเราก็สามารถลดเวลาได้ด้วยการทำ Script สั้น ๆ เช่นกรณีนี้ ต้องการสร้าง Directory ตามโครงสร้างนี้

├── config
│   └── webui
├── data
│   ├── director
│   ├── storage
│   └── webui
├── mysql
│   ├── data
│   └── log

เราสามารถใช้คำสั่งสั้น ๆ ข้างล่าง เพื่อสร้างโฟลเดอร์

mkdir -p {data/{director,storage,webui},config/webui,mysql/{data,log}}

และกรณีอื่น ๆ อีก ไปลองกันได้ว่าผลลัพธ์จะได้ออกมายังไง

mkdir test{1..50}
mkdir -p test{1..50}/sub{1..50}
mkdir {a-z}12345 
mkdir {1,2,3}
mkdir test{01..10}
mkdir -p `date '+%y%m%d'`/{1,2,3} 
mkdir -p $USER/{1,2,3}

จบปิ๊ง !!

Simulate keyboard input and mouse activity and more on Raspberry Pi

นานมาแล้ว (หรือช่วงนี้ก็มี 555) มีโปรแกรมกลุ่มพวกคลิกโฆษณาอัตโนมัติ ได้รับความนิยมอย่างล้นหลาม ใคร ๆ ก็ทำงานบนอินเตอร์เนตกัน จนมีประโยคสุดฮิตสแปมมาอยู่เนือง ๆ

โดยหลัก ๆ ละโปรแกรมเหล่านี้ก็จะจำลองการทำงานของเมาส์และคีย์บอร์ดแหล่ะ และวันนึงก็ได้ใช้ ด้วยความที่ตัว Raspberry Pi ที่ใช้งานอยู่จำเป็นต้องจำลองการเลื่อน/คลิกเมาส์และใช้คีย์บอร์ดขึ้นมา xdotool ช่วยคุณได้ เริ่มติดตั้งกันเลย

sudo apt-get install xdotool

ตัวอย่างการใช้งานก็ง่าย ๆ สร้างสคริปท์ขึ้นมา อาจจะทำงานผ่าน Crontab ก็ได้ เช่น ต้องการ
Resize all visible gnome-terminal windows

#!/bin/bash

WIDS=`xdotool search --onlyvisible --name "gnome-terminal"`
for id in $WIDS; do
  xdotool windowsize $id 500 500
done

# As of version 2.20100623, you can do this simpler version of above:
xdotool search --onlyvisible --classname "gnome-terminal" windowsize %@ 500 500

จบปิ๊ง   !!

ป.ล.
อยากใช้ก็มีให้ใช้ได้ทันที แบบนี้สิดี
Github : https://github.com/jordansissel/xdotool

Convert pdf to image – แปลงไฟล์ PDF เป็นรูปภาพด้วย Linux บน Windows กัน

จั่วหัวมาแบบนี้ก็อย่าเพิ่งสับสน ณ วันนี้ (พฤษภาคม 2561) Linux กับ Windows เป็นมิตรกันมากกกกกกกกกซึ่งก็ถือเป็นเรื่องที่ดีจริง ๆ สำหรับคนในวงการคอมพิวเตอร์และทั่ว ๆ ไปถือว่าดีกับทุกฝ่ายหล่ะกัน (ลองหาข่าวช่วงก่อนหน้านี้ดูคร่าว ๆ ได้ว่าสังคมสรรเสริญเรื่องนี้กันขนาดไหน) ถ้าใครอยากลองใช้งาน Linux บน Windows ก็ทำตามคร่าว ๆ ประมาณนี้ (แบบละเอียดก็ตามเอกสารตัวนี้ได้เลย)

  1. เปิด PowerShell รันคำสั่งนี้

    รอสักครู่เพื่อให้ระบบเปิดใช้งานฟีเจอร์ “Windows Subsystem for Linux”
  2. เปิด Microsoft Store เพื่อติดตั้ง Ubuntu ต่อได้เลย

    ขนาดไฟล์ก็ไม่ใหญ่มาก
  3. พอติดตั้งเสร็จเราก็เริ่มใช้งานกันได้เลย
  4. จะเห็นได้ว่าเวอร์ชั่นที่ติดตั้งยังเป็น 16.04 (Xenial Xerus) อยู่ ณ ปัจจุบันก็ 18.04 ไปเรียบร้อยแล้ว แต่แค่นี้ก็เพียงพอสำหรับการใช้งานละ ^_^

พอระบบพร้อมสำหรับใช้งานก็มาเริ่มแปลงไฟล์ PDF เป็นรูปภาพกัน (มันมีที่มานิดนึงว่าทำไมต้องใช้วิธีแบบนี้ เนื่องจากเรามีไฟล์ PDF จำนวนมากก จำนวนหนึ่งที่ต้องแปลงเป็นไฟล์รูปภาพแบบด่วน ๆ ลองค้นเครื่องมือบนวินโดวส์ที่เป็นเครื่องมือฟรีรวมถึงออนไลน์ด้วยก็พบว่ามีจำนวนน้อยเกินไป ตัวดี ๆ ก็ Commercial ซะ เศร้าาา และบวกกับความขี้เกียจและเคยชินว่า Linux แปลงไฟล์ตามโจทย์นี้แบบสะดวกเลย แค่นั้นแหล่ะ) เริ่มเลยหล่ะกัน

  1. สร้างไฟล์ Bash Script มา 1 ไฟล์
    #!/bin/bash
    for file in *.pdf ; do
      convert -verbose -density 300 -quality 100 "${file}" "${file%.*}".png
    done

    โดยเราใช้โปรแกรมที่ชื่อว่า convert ที่อยู่ใน imagemagick package ก็ให้ติดตั้งโดยใช้คำสั่ง

    sudo apt-get install imagemagick

    ซึ่ง Bash script ข้างบนจะทำการแปลงทุกไฟล์ที่นามสกุล *.pdf ใน Directory ปัจจุบัน และบันทึกเป็นไฟล์รูปภาพนามสกุล *.png ส่วน พารามิเตอร์ที่ใช้ ก็ตามไปอ่านต่อที่นี่ได้

  2. ลองทดสอบกัน สมมุติเรามีไฟล์ pdf จำนวนหนึ่ง ตัวอย่างมีไฟล์ 2 ไฟล์ ไฟล์ละ 2 หน้า (ไฟล์เดียวกันนั่นแหล่ะ)

  3. รัน Bash Script เพื่อแปลงไฟล์เป็นรูปภาพซะ

    เราจะได้ไฟล์รูปภาพ 1 ไฟล์ ต่อ 1 หน้ารันลำดับชื่อไฟล์
  4. จบปิ๊ง

ปรับปรุงข้อมูลวันหยุดราชการ (Holiday) กัน

สำหรับประชาชนคนไทยแล้วคำว่า “ในเวลาราชการ” นี่น่าจะคุ้นเคยกันเป็นอย่างดี เรามักเห็นคำนี้ติดตามหน่วยงานราชการ แล้วคำว่าในเวลาราชการนี่มันยังไง เอาแบบกำปั้นทุบดิน ก็คือวันที่ไม่ใช่วันหยุดราชการนั่นแหล่ะ 😛

แล้ววันหยุดราชการนี่เราก็เริ่มยึดตาม “ประกาศกำหนดวันหยุดราชการนักขัตฤกษ์ พระพุทธศักราช ๒๔๕๖” ซึ่งพระบาทสมเด็จพระมงกุฎเกล้าเจ้าอยู่หัว รัชกาลที่ ๖ ทรงออกประกาศดังกล่าว ถ้าใครจะศึกษารายละเอียดบล็อกนี้ก็อธิบายไว้เป็นอย่างดี

ทีนี้ตัวที่เกี่ยวข้องกับโรงพยาบาลยังไงบ้าง หลาย ๆ หน่วยงานที่มีระบบคอมพิวเตอร์ไว้ทำงานอย่างเช่นโรงพยาบาล หน่วยบริการหรืออื่น ๆ นี่ก็มักมีตารางวันหยุดในปีนั้น ๆ สำหรับการทำงาน ซึ่งก็จะเป็นตาราง ตารางนึงตามแต่ละเวนเดอร์ (Vendor) สร้างขึ้นรายละเอียดแตกต่างกันบ้าง แต่ส่วนใหญ่แล้ววัตถุประสงค์ก็เพื่อระบุว่าวันใดคือวันหยุดราชการนั่นแหล่ะ ปกติหน้าที่อัพเดตข้อมูลนี้ก็จะเป็นของผู้ดูแลระบบของหน่วยบริการ ข้อมูลพวกนี้ส่วนใหญ่ก็มาจาก ประกาศทางราชการหรือเว็บทั่ว ๆ ไป เช่น วิกิพีเดีย

และอีกเว็บไซต์ก็ myhora ซึ่งมีบริการ iCal บริการ

จะเห็นได้ว่ามีไฟล์ CSV (Comma-separated values) ให้เราได้ใช้ด้วย งั้นเราก็มาปรับปรุงวันหยุดราชการด้วยไฟล์ตัวนี้กัน

  1. เริ่มต้นก็ดาวน์โหลดมาซะ
    wget -O th_holiday.csv http://www.myhora.com/calendar/ical/holiday.aspx?2561.csv

    หน้าตาข้อมูลไฟล์คร่าว ๆ ก็ประมาณนี้

  2. นำเข้าข้อมูลข้างต้นลงในฐานข้อมูลของเราด้วยคำสั่ง LOAD DATA INFILE (สร้างตารางชั่วคราว th_holiday ไว้รอรับด้วย )
    DROP TABLE IF EXISTS th_holiday;
    CREATE TABLE IF NOT EXISTS th_holiday(
        Subject       	VARCHAR(255) NULL
        ,Start_Date    	DATE NOT NULL
        ,Start_Time    	TIME NULL
        ,End_Date      	DATE NULL
        ,End_Time      	TIME NULL
        ,All_day_event 	VARCHAR(4) NOT NULL
        ,Description   	VARCHAR(255) NOT NULL
        ,Show_time_as  	INTEGER  NOT NULL
        ,Location      	VARCHAR(30)
    );
    
    TRUNCATE th_holiday;
    LOAD DATA LOCAL INFILE 'th_holiday.csv' 
    INTO TABLE th_holiday
    FIELDS TERMINATED BY ',' 
    ENCLOSED BY '"'
    ESCAPED BY '"'
    LINES TERMINATED BY '\r\n'
    (`Subject`, @start_date, `Start_Time`, `End_Date`, `End_Time`, `All_day_event`, `Description`, `Show_time_as`, `Location`)
    SET start_date = STR_TO_DATE(@start_date, '%d/%m/%Y');
  3. เป็นอันเสร็จสิ้น ทีนี้ก็นำข้อมูลนี้ไปปรับปรุงในตารางของแต่ละ HIS

 

 

Automatically backup MySQL database to Google Drive

ประเด็นหลัก ๆ ของบล็อกนี้ก็เรื่องของการสำรองฐานข้อมูลนั่นแหล่ะ ต่างกันนิดหน่อยกับคำว่าตัวสำรอง เราสำรองเพราะเห็นว่าสิ่งนั้นสำคัญแต่ตัวสำรองคือยังไม่สำคัญนะให้รอ ก็ได้แค่นั้นแค่ตัวสำรอง

เดี๋ยวลองไล่ลำดับ ขั้นตอนในกระบวนการนี้ด้วยกัน

  1. เริ่มสำรองข้อมูล ในที่นี้คือฐานข้อมูลของ MySQL ด้วย Tool มาตรฐานคือ mysqldump (ส่วนเรื่องพารามิเตอร์ในคำสั่ง อะไรยังไง จะเอาอะไร ไม่เอาอะไร อ่านต่อได้ที่นี่)
  2. บีบอัดไฟล์ให้ขนาดเล็กลง
  3. เก็บไฟล์ไว้ที่เครื่องโลคอลนิดหน่อยอีก 30 วันค่อยมาลบหล่ะกัน (ทั้งนี้ทั้งนั้นก็ขึ้นกับความต้องการด้วยนะว่าเหมาะสมแค่ไหน)
  4. ทำการอัพโหลดข้อมูลที่สำรองได้ขึ้น Google Drive ผ่าน Google Drive CLI Client ตัวนึงที่ชื่อว่า gdrive (จุดประสงค์หลักคือเพื่อให้มีแหล่งเก็บอื่นเพิ่ม) ก่อนการใช้งานจำเป็นต้องอนุญาตให้ gdrive สามารถเข้าถึง Google Drive ของเราได้ก่อน
    1. อนุญาตสิจ๊ะ
    2. คัดลอก Token ที่ได้ เพื่อมาใช้ในโปรแกรม
  5. ทั้งหมดทั้งมวลให้ทำงานอัตโนมัติ โดยการใช้ crontab (สงสัยวิธีใช้งานก็ตามอ่านกันที่นี่นะ #เหมือนจะขี้เกียจ #55555)

โดยขั้นตอนข้างต้นเราเขียนเชลล์สคริปท์สั้น ๆ สำหรับทำงานแบบรูทีนตามนี้

ผลลัพธ์ที่ได้ก็ตามนี้

ป.ล. 1
การสำรองข้อมูลเป็นเรื่องที่สำคัญพอ ๆ กับการทดสอบไฟล์ที่สำรองได้นั้นสามารถใช้งานได้หรือไม่

ป.ล 2
gdrive – gdrive is a command line utility for interacting with Google Drive.
pv – monitor the progress of data through a pipe.

 

Watermark images with file name

เช้าวันนี้ (2 พฤศจิกายน 2559) มาพร้อมกับงานด่วน
– Watermark ไฟล์รูปด้วยชื่อไฟล์ (ต้นฉบับมาแบบนี้ -*-)
– ไฟล์รูปมีคร่าว ๆ ก็เกือบ 100 รูป ความขี้เกียจเข้าครอบงำโดยพลัน
selection_030

selection_031

#!/bin/bash
#
# NAME:		WatermarkFilename	
# AUTHOR:	MF
# A script to add a watermark and overwrite all images in a directory.


savedir=".originals"
mkdir -p $savedir

for image in *png *jpg *jpeg *gif
do
	if [ -s $image ] ; then   # non-zero file size

		width=$(identify -format %w $image)
		filename=$(basename "$image")
		fname="${filename%.*}"
		ext="${filename##*.}"
		fullpath="$(dirname $(readlink -f "${image}"))/${image##*/}"

		convert -background '#cccccc' \
		-fill white -gravity center \
		-font loma -pointsize 30 -size ${width}x60 caption:$fname \
		$image +swap -gravity south -composite new-$image
		mv $image $savedir
		mv new-$image $image
		echo "Watermarked $image successfully"		
	fi
done

ป.ล.
– เสียเวลาไปกับการตรวจสอบข้อมูลให้ตรงกับชื่อไฟล์ซะมากกว่า
– ไฟล์ตัวอย่างจาก https://unsplash.com/
– ใช้แพคเกจ imagemagick

Find and log which top 5 processes are taking high cpu

เวลาคอมพิวเตอร์ตระกูล *nix พบปัญหา อันดับแรก ๆ ที่จะเริ่มทำเพื่อแก้ปัญหาและช่วยชีวิตเราก็คือเปิด Log เกิดปัญหาปุ๊บเปิด Log ก่อนเลยแต่บางกรณีเราก็มอนิเตอร์ผ่านโปรแกรม/คำสั่งตัวอื่น โดยทั่ว ๆ ไปมักจะใช้ top เพื่อมอนิเตอร์การทำงานของคอมพิวเตอร์ ซึงโปรแกรมจะแสดงสถานะของ Memory, CPU, Process Terminal_042

top นี่คือต้องมีเวลานั่งดูเพราะผลลัพธ์ที่ได้จะแสดงออกมาแบบเรียลไทม์ อีกทางเลือกหนึ่งก็คือใช้คำสั่ง ps

ps – report a snapshot of the current processes.

 a@b  ~  ps -aux                                    1 ↵  481  11:31:05 
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0 185556  6264 ?        Ss   09:55   0:02 /sbin/init spla
root         2  0.0  0.0      0     0 ?        S    09:55   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    09:55   0:00 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   09:55   0:00 [kworker/0:0H]
root         7  0.0  0.0      0     0 ?        S    09:55   0:05 [rcu_sched]
root         8  0.0  0.0      0     0 ?        S    09:55   0:00 [rcu_bh]
root         9  0.0  0.0      0     0 ?        S    09:55   0:00 [migration/0]
root        10  0.0  0.0      0     0 ?        S    09:55   0:00 [watchdog/0]
root        11  0.0  0.0      0     0 ?        S    09:55   0:00 [watchdog/1]

ps ใช้แล้วก็จบไง จะดูอีกก็สั่งอีก (ใช้ watch ดูแบบ top ก็ได้นะ แต่จะใช้ watch ก็ไปใช้ top ละเอียดกว่าเยอะ) แต่ในกรณีที่ต้องการเก็บ Log ผลลัพธ์ที่ได้จาก ps เพื่อดูการทำงาน เช่นอาจจะต้องการมอนิเตอร์โปรเสสที่ใช้งานสูง ๆ หรือมอนิเตอร์ดูภายหลังว่าใครกำลังแอบแดกเมมมหาโหด ก็ทำแบบนี้ได้

while true; do 
    ps auxf | sort -nrk 3,3 | head -n 5 >> log.log; 
    sleep 1; 
done

ผลลัพธ์ที่ได้

a@b  ~  tail -f log.log                              ✓  488  11:40:13 
a        6019 28.6  4.0 2189732 663568 tty2   Sl+  09:57  28:48 /usr/lib/firefox/firefox
a        4376  4.7  1.2 2334564 198912 tty2   Sl+  09:57   4:49              \_ /usr/bin/gnome-shell
root      4222  2.7  0.4 534160 79804 tty2     Sl+  09:57   2:43          \_ /usr/lib/xorg/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -background none -noreset -keeptty -verbose 3

 

 

Dirty Lab : Import many delimited files into MySQL

ดูโค๊ดเอาหล่ะกันเน๊อะ มีความขี้เกียจตั้งแต่เห็นจำนวนไฟล์ละ (คือแบบเยอะมากกกกกกก) แต่จำเป็นต้องใช้ก็เลยเกิดแลปแบบด่วน ๆ
– ใช้โครงสร้างของ HDC
– ไฟล์ที่นำเข้าอยู่ในรูปแบบของโครงสร้างมาตรฐานข้อมูลด้านสุขภาพ กระทรวงสาธารณสุข (43 แฟ้ม)
– ปล้ำ Servlet ของ HDC โดยไม่ติดตั้งระบบนี่ดูยาก ๆ อ่ะ รอปรึกษา Phoubon Ict
– อันนี้ช่วงรอไฟล์นำเข้า

#!/bin/sh
#Import delimited file to database;

IMPORTEDFOLDER="imported"

fileCount=0
fileName=""
filePath=""

mkdir -p "../${IMPORTEDFOLDER}"

for zip in *.zip; do
    zip_filename="${zip%%.*}"
    unzip "${zip}" -d "${zip_filename}"
    mv -f "${zip}" "../${IMPORTEDFOLDER}"
    
    for file in $(find ./ -name '*.txt' -or -name '*.TXT'); do
        fileName=${file##*/}
        fileName=${fileName%.txt}
        filePath="$(dirname $(readlink -f "${file}"))/${file##*/}"
        
        #TODO: Extend to GNU Parallel
        sh importdelimited.sh "${filePath}" "${fileName}" 
        
        fileCount=$((fileCount+1))
    done
    
    #rm -rf "${zip_filename}"
    
done

echo "${fileCount} files completed."

สคริปสำหรับนำเข้าฐานข้อมูลของ MySQL

#!/bin/sh
#Import delimited file to database;
#Usage : sh importdelimited.sh {Source} {Target}

LOGFILE="importlog.log"
DB="hdc"
USERDB="a1a1a1"
PASSDB="b1b1b1"
SQL=""

SQL="SET SESSION sql_mode=''; LOAD DATA LOCAL INFILE '$1' REPLACE INTO TABLE $2 FIELDS TERMINATED BY '|' LINES TERMINATED BY '\r\n' IGNORE 1 LINES;"
echo "$(date -u) $2:${SQL}" >> "../${LOGFILE}" 2>&1
mysql -u${USERDB} -p${PASSDB} ${DB} -e "${SQL}"
rm -f $1

ส่วนใครจะปรับโค๊ดให้ดูเมพขึ้นก็ตามสบายนะครับ ถ้าให้ดีก็ดิสคัสกันต่อก็ได้ เรานูปเชลสคริปท์ อย่างอื่นก็นูป (ดัก)