Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม Bash

Bash Aliases ที่จำเป็น จะทำให้คุณทำงานได้เร็วขึ้น

Bash Alias เป็นวิธีเสริมหรือทับคำสั่ง Bash ด้วยคำสั่งใหม่ ทำให้ผู้ใช้ปรับแตประสบการณ์ใน POSIX Terminal ได้ง่าย มัก Define ใน $HOME/.bashrc หรือ $HOME/bash_aliases (ต้องโหลดโดย $HOME/.bashrc)

Distro ส่วนใหญ่เพิ่ม Aliases ยอดนิยมใน .bashrc Default ของ User ใหม่ ตัวอย่าง Syntax:

alias ls='ls -F'
alias ll='ls -lh'

ไม่ใช่ทุก Distro ที่มาพร้อม Aliases หากเพิ่มเอง ต้อง Load เข้า Bash Session ปัจจุบัน:

$ source ~/.bashrc

หรือปิด Terminal เปิดใหม่เพื่อ Reload Config File

ด้วย Aliases นี้ พิมพ์ ll ได้ผล ls -l พิมพ์ ls ได้ผลแทน ls ธรรมดา

Aliases นี้ดีแล้ว แต่เพียงขุ่ยนำเท่านั้น นี่คือ Top 10 Bash Aliases ที่ลองใช้แล้วไม่ว่างอยู่อีก

ตั้งค่าก่อน

ก่อนเริ่ม สร้างไฟล์ ~/.bash_aliases:

$ touch ~/.bash_aliases

ตรวจสอบว่าโค้ดนี้อยู่ใน ~/.bashrc:

if [ -e $HOME/.bash_aliases ]; then
source $HOME/.bash_aliases
fi

หากลอง Aliases ในบทความ ใส่ใน .bash_aliases แล้ว Load ด้วย source ~/.bashrc

จัดเรียงตามขนาดไฟล์

หากเริ่มใช้คอมพิวเตอร์ด้วย GUI File Managers เช่น Nautilus (GNOME), Finder (MacOS), Explorer (Windows) คงเคยจัดเรียงไฟล์ตามขนาด ทำได้ใน Terminal แต่ไม่กระชับ

เพิ่ม Alias นี้ใน Config บน GNU System:

alias lt='ls --human-readable --size -1 -S --classify'

Alias นี้แทน lt ด้วย ls แสดงขนาดแต่ละ Item จัดเรียงตามขนาด คอลัมน์เดียว พร้อม Notation แสดงประเภทไฟล์ Load Alias ใหม่แล้วลอง:

$ source ~/.bashrc
$ lt
total 344K
140K configure*
44K aclocal.m4
36K LICENSE
32K config.status*
24K Makefile
24K Makefile.in
12K config.log
8.0K README.md
4.0K info.slackermedia.Git-portal.json
4.0K git-portal.spec
4.0K flatpak.path.patch
4.0K Makefile.am*
4.0K dot-gitlab.ci.yml
4.0K configure.ac*
0 autom4te.cache/
0 share/
0 bin/
0 install-sh@
0 compile@
0 missing@
0 COPYING@

บน MacOS หรือ BSD ls ไม่มี Options เดียวกัน Alias นี้ใช้แทน:

alias lt='du -sh * | sort -h'

ผลลัพธ์ต่างออกไปนิดหน่อย:

$ du -sh * | sort -h
0 compile
0 COPYING
0 install-sh
0 missing
4.0K configure.ac
4.0K dot-gitlab.ci.yml
4.0K flatpak.path.patch
4.0K git-portal.spec
4.0K info.slackermedia.Git-portal.json
4.0K Makefile.am
8.0K README.md
12K config.log
16K bin
24K Makefile
24K Makefile.in
32K config.status
36K LICENSE
44K aclocal.m4
60K share
140K configure
476K autom4te.cache

จริงๆ บน Linux คำสั่งนี้ก็มีประโยชน์ เพราะ ls แสดง Directories และ Symlinks เป็นขนาด 0 ซึ่งอาจไม่ใช่ข้อมูลที่ต้องการ ตัวเลือกอยู่ที่คุณ

ขอบคุณ Brad Alexander สำหรับไอเดีย Alias นี้

ดูเฉพาะ Mounted Drives

คำสั่ง mount เดิมเรียบง่าย คำสั่งเดียวได้รายการ Mounted Filesystems ทั้งหมด ใช้ดู Drives ที่ต่ออยู่ ผลลัพธ์จัดการได้ เพราะคอมพิวเตอร์เก่าไม่มี USB Port มากกว่า 3-4

ตอนนี้ซับซ้อนขึ้น ระหว่าง LVM, Physical Drives, Network Storage, Virtual Filesystems ผล mount ยากต่อการ Parse:

sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,seclabel,size=8131024k,nr_inodes=2032756,mode=755)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
[...]
/dev/nvme0n1p2 on /boot type ext4 (rw,relatime,seclabel)
/dev/nvme0n1p1 on /boot/efi type vfat (rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=ascii,shortname=winnt,errors=remount-ro)
[...]
gvfsd-fuse on /run/user/100977/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=100977,group_id=100977)
/dev/sda1 on /run/media/seth/pocket type ext4 (rw,nosuid,nodev,relatime,seclabel,uhelper=udisks2)
/dev/sdc1 on /run/media/seth/trip type ext4 (rw,nosuid,nodev,relatime,seclabel,uhelper=udisks2)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)

แก้ด้วย Alias แบบนี้:

alias mnt="mount | awk -F' ' '{ printf \"%s\t%s\n\",\$1,\$3; }' | column -t | egrep ^/dev/ | sort"

Alias ใช้ awk Parse Output ของ mount ตาม Column ลดเหลือสิ่งที่ต้องการ (Hard Drives ไม่ใช่ Filesystems ที่ Mounted):

$ mnt
/dev/mapper/fedora-root /
/dev/nvme0n1p1 /boot/efi
/dev/nvme0n1p2 /boot
/dev/sda1 /run/media/seth/pocket
/dev/sdc1 /run/media/seth/trip

บน MacOS mount ไม่ Verbose มาก Alias อาจ Overkill แต่ถ้าชอบรายงานกระชับ ลอง:

alias mnt='mount | grep -E ^/dev | column -t'

ผลลัพธ์:

$ mnt
/dev/disk1s1 on / (apfs, local, journaled)
/dev/disk1s4 on /private/var/vm (apfs, local, noexec, journaled, noatime, nobrowse)

ค้นหาคำสั่งใน History ด้วย grep

บางครั้งคิดวิธีทำใน Terminal แล้วสัญญาใจว่าจะไม่ลืม แล้ว 1 ชั่วโมงผ่านไป ลืมสนิท

ค้นหาใน Bash History ใครต้องทำบ้าง หากจำคำสั่งที่ต้องการชัดเจน ใช้ Ctrl+R Reverse Search แต่บางครั้งจำคำสั่งไม่ได้

Alias ช่วยงานนี้:

alias gh='history|grep'

ตัวอย่างการใช้:

$ gh bash
482 cat ~/.bashrc | grep _alias
498 emacs ~/.bashrc
530 emacs ~/.bash_aliases
531 source ~/.bashrc

จัดเรียงตามเวลาแก้ไข

ทุกวันจันทร์: มาทำงาน เปิด Terminal พบว่าลืมทำอะไรวันศุกร์ ต้องการ Alias แสดงไฟล์ที่แก้ไขล่าสุด

ใช้ ls สร้าง Alias ช่วยหาจุดที่หยุด:

alias left='ls -t -1'

Output เรียบง่าย ขยายด้วย Option --long ได้ Alias แสดงแบบนี้:

$ left
demo.jpeg
demo.xcf
design-proposal.md
rejects.txt
brainstorm.txt
query-letter.xml

นับไฟล์

ต้องรู้ว่ามีไฟล์กี่ไฟล์ใน Directory วิธีแก้เป็นตัวอย่างคลาสสิกของ UNIX Command Construction: List ไฟล์ด้วย ls ควบคุม Output ให้คอลัมน์เดียวด้วย -1 Pipe ไป wc (Word Count) นับบรรทัด

สาธิตปรัชญา UNIX ให้ User สร้าง Solution เองจาก Component เล็กๆ คำสั่งนี้พิมพ์เยอะหากทำหลายครั้ง/วัน และไม่ทำงานกับ Directory ของ Directories โดยไม่ใช้ -R ซึ่งเพิ่มบรรทัดใหม่ ทำให้ใช้ไม่ได้

Alias นี้ทำให้ง่าย:

alias count='find . -type f | wc -l'

นับไฟล์ ไม่รวม Directories แต่ ไม่รวม เนื้อหาใน Directories หากมี Project Folder มี 2 Directories แต่ละอันมี 2 ไฟล์ Alias คืนค่า 4 เพราะมี 4 ไฟล์ใน Project ทั้งหมด

$ ls
foo bar
$ count
4

สร้าง Python Virtual Environment

เขียน Python?

เขียน Python มาก?

ถ้าใช่ รู้ว่าสร้าง Python Virtual Environment ต้องพิมพ์อย่างน้อย 53 Keystrokes

มากเกิน 49 ตัว แก้ได้ด้วย 2 Aliases ใหม่ ve และ va:

alias ve='python3 -m venv ./venv'
alias va='source ./venv/bin/activate'

รัน ve สร้าง Directory venv มี Filesystem Virtual Environment ปกติสำหรับ Python3 va Activate Environment ใน Shell ปัจจุบัน:

$ cd my-project
$ ve
$ va
(venv) $

เพิ่ม Progress Bar ตอน Copy

ทุกคนเยาะ Progress Bar เพราะ Negative Infamous Inaccurate แต่ในใจลึกๆ ทุกคนอยากได้ UNIX cp ไม่มี Progress Bar แต่มี Option -v Verbosity Echo ชื่อไฟล์ที่ Copy ไป Terminal Hack ดี แต่ไม่ค่อยงานตอน Copy ไฟล์ใหญ่ ต้องการรู้ว่า Transfer ไปแล้วเท่าไหร่

คำสั่ง pv ให้ Progress Bar ตอน Copy แต่ไม่ค่อยเป็น Default App ส่วน rsync รวมใน Default Installation ของเกือบทุก POSIX System และยอมรับว่าเป็นวิธี Copy ฉลาดที่สุดทั้ง Remote และ Local

ยิ่งไปกว่านั้น มี Progress Bar Built-in!

alias cpv='rsync -ah --info=progress2'

ใช้ Alias เหมือน cp:

$ cpv bigfile.flac /run/media/seth/audio/
3.83M 6% 213.15MB/s 0:00:00 (xfr#4, to-chk=0/4)

Side Effect น่าสนใจ: rsync Copy ทั้ง Files และ Directories โดยไม่ต้อง Flag -r ที่ cp ต้องการ

ป้องกันอุบัติเหตุลบไฟล์

ไม่ควรใช้ rm แม้ Manual rm ก็บอกว่า:

Warning: If you use 'rm' to remove a file, it is usually possible to recover the contents of that file. If you want more assurance that the contents are truly unrecoverable, consider using 'shred'.

หากต้องการลบไฟล์ ควร Move ไป Trash เหมือนใช้ Desktop

POSIX ทำให้ง่าย เพราะ Trash เป็น Location จริงใน Filesystem Location อาจเปลี่ยนตาม Platform: FreeDesktop Trash อยู่ ~/.local/share/Trash MacOS อยู่ ~/.Trash แต่มันคือ Directory ใส่ไฟล์ที่อยากไม่อยู่หน้าตา จนกว่าจะลบถาวร

Alias ง่ายๆ ทิ้งไฟล์/โฟลเดอร์ไป Trash จาก Terminal:

alias tcn='mv --force -t ~/.local/share/Trash '

Alias ใช้ Flag mv ที่นิยมน้อย ให้ระบุไฟล์ที่ย้ายเป็น Argument สุดท้าย ไม่ต้อง List ก่อน ปกติ ตอนนี้ใช้คำสั่งใหม่ Move ไป System Trash:

$ ls 
foo bar
$ tcn foo
$ ls
bar

ไฟล์ "หาย" แต่นำกลับมาจาก System Trash ได้ เมื่อตระหนักในความเหงื่อเย็นว่ายังต้องการ ต้องขอขอบคุณ Developer Bash และ mv ด้วย

Note: หากต้องการคำสั่ง Trash แข็งแกร่ง FreeDesktop Compliant ดู Trashy

ลดความซับซ้อน Git Workflow

ทุกคนมี Workflow แตกต่าง แต่มักมีงานซ้ำๆ หากทำงานกับ Git บ่อย อาจมี Sequence ที่พิมพ์ซ้ำตลอดวัน อาจกลับ Branch Master Pull Latest Changes บ่อยๆ หรือสร้าง Tags Push Remote หรืออย่างอื่น

ไม่ว่าจะเป็น Git Incantation ใดที่เบื่อพิมพ์ อาจบรรเทาอาการด้วย Bash Alias ขอบคุณความสามารถ Pass Arguments ไป Hooks Git มี Commands Introspective หลากหลาย ช่วยไม่ต้องทำ Feats แปลกๆ ใน Bash

ตัวอย่าง ใน Bash หา Top-level Directory ของ Project ยาก (ตาม Bash มัน Arbitrary Designation เนื่องจาก Root คือ Top Level จริง) แต่ Git รู้ Top Level ด้วย Query เรียบง่าย ศึกษา Git Hooks จะหาข้อมูลได้มากที่ Bash ไม่รู้ แต่ Leverage ได้ด้วย Bash Alias

Alias หา Top Level Git Project ไม่ว่าจะอยู่ลึกแค่ไหน แล้ว cd ไป Master Branch และ Git Pull:

alias startgit='cd `git rev-parse --show-toplevel` && git checkout master && git pull'

Alias แบบนี้ไม่ได้ Universal แต่นำเสนอว่า Alias เรียบง่ายลดการนำทาง คำสั่ง และการรอ Prompt มาก

Alias เรียบง่ายกว่า และ Universal กว่าคือ กลับไป Top Level ของ Git Project Alias นี้มีประโยชน์เพราะตอนทำงาน Project นั้นกลายเป็น "Home Directory ชั่วคราว" ควร "กลับบ้าน" ได้ง่ายเท่า Home จริง:

alias cg='cd `git rev-parse --show-toplevel`'

ตอนนี้ cg พาคุณไป Top ของ Git Project ไม่ว่าจะลึกแค่ไหน

เปลี่ยน Directory และดูเนื้อหาพร้อมกัน

เคย (ลักลอบ) เสนอโดย นักวิทยาศาสตร์ชั้นนำ ว่าแก้ปัญหาพลังงานโลกได้ โดยใช้พลังงานที่ Geeks ใช้พิมพ์ cd ตามด้วย ls

Pattern ปกติ เพราะตอนเปลี่ยน Directory มักอยากดูรอบๆ

แต่ "เดิน" Directory Tree ไม่ต้อง Start-and-stop

ตัวนี้ Cheat เพราะไม่ใช่ Alias แต่มันเป็น Excuse ดีสำรวจ Bash Functions Aliases ดีสำหรับ Quick Substitution แต่ Bash 允许 เพิ่ม Local Functions ใน .bashrc (หรือ Functions File แยก Load เข้า .bashrc เหมือน Aliases File)

เพื่อ Modular สร้างไฟล์ ~/.bash_functions ให้ .bashrc Load:

if [ -e $HOME/.bash_functions ]; then
source $HOME/.bash_functions
fi

ใน Functions File ใส่โค้ด:

function cl() {
DIR="$*";
# if no DIR given, go home
if [ $# -lt 1 ]; then
DIR=$HOME;
fi;
builtin cd "${DIR}" && \
# use your preferred ls command
ls -F --color=auto
}

Load Function ลง Bash Session แล้วลอง:

$ source ~/.bash_functions
$ cl Documents
foo bar baz
$ pwd
/home/seth/Documents
$ cl ..
Desktop Documents Downloads
[...]
$ pwd
/home/seth

Functions ยืดหยุ่นกว่า Aliases แต่มาพร้อมความรับผิดชอบ ตรวจสอบว่า Code Makes Sense และทำงานต้อง Aliases ควร Simple แต่ Useful สำหรับการปรับพฤติกรรม Bash อย่างจริงจัง ใช้ Functions หรือ Custom Shell Scripts บันทึกใน PATH

เพื่อความเป็นทางการ มี Clever Hacks Implement cd และ ls Sequence เป็น Alias ได้ หากอดทนพอ Sky is the limit แม้ Aliases ต่ำต้อย

เริ่ม Aliasing และ Functioning

ปรับแต่ง Environment ทำให้ Linux สนุก เพิ่มประสิทธิภาพ ทำให้ชีวิต Linux เปลี่ยนแปลง เริ่ม Aliases เรียบง่าย ขึ้นสู่ Functions โพสต์ Must-have Aliases ใน Comments นะครับ!