72 คะแนน โดย GN⁺ 2026-03-27 | 3 ความคิดเห็น | แชร์ทาง WhatsApp
  • สรุปวิธีเพิ่มความเร็วและประสิทธิภาพการทำงานในสภาพแวดล้อมเชลล์ด้วยการใช้ คีย์ลัดบนคีย์บอร์ดและการผสมคำสั่ง อย่างหลากหลาย
  • ใช้คีย์ลัดพื้นฐานอย่าง CTRL + W, U, K, Y เพื่อแก้ไขบรรทัด, ใช้ CTRL + A/E, ALT + B/F เพื่อย้ายเคอร์เซอร์ และใช้ reset เพื่อกู้คืนเทอร์มินัลได้
  • ใน Bash และ Zsh สามารถใช้ CTRL + R เพื่อค้นหาประวัติคำสั่ง, ใช้ !!·!$·ESC+. เพื่อนำคำสั่งก่อนหน้ากลับมาใช้ซ้ำ, และใช้ Brace Expansion กับ Globstar เพื่อทำงานซ้ำแบบอัตโนมัติ
  • ใช้ความสามารถขั้นสูงอย่าง Process Substitution, tee, bg/disown เพื่อควบคุมโปรเซสและจัดการล็อกได้อย่างมีประสิทธิภาพยิ่งขึ้น
  • หากใช้งานเชลล์ได้คล่องเหมือนเป็น กล่องเครื่องมือ จะช่วยเพิ่มทั้งประสิทธิภาพการทำงานและสมาธิได้ โดยหัวใจสำคัญคือค่อย ๆ สร้างนิสัยใช้คีย์ลัดทีละอย่าง

คีย์ลัดและความสามารถพื้นฐานที่ใช้ได้กับเชลล์แทบทุกตัว

  • ชุดคีย์ CTRL + W, U, K, Y เป็นคีย์ลัดสำหรับแก้ไขบรรทัดที่ช่วย ลบหรือกู้คืนคำหรือส่วนของบรรทัดด้านหน้า/ด้านหลังจากตำแหน่งเคอร์เซอร์ได้อย่างรวดเร็ว

    • CTRL + W ลบคำที่อยู่ก่อนเคอร์เซอร์
    • CTRL + U ตัดข้อความจากเคอร์เซอร์ไปจนถึงต้นบรรทัด และสามารถวางกลับได้ด้วย CTRL + Y
    • CTRL + K ตัดข้อความจากเคอร์เซอร์ไปจนถึงท้ายบรรทัด
    • CTRL + A / E ย้ายไปต้นและท้ายบรรทัด, ALT + B / F ย้ายทีละคำไปด้านหน้าและด้านหลัง
    • ในเทอร์มินัลส่วนใหญ่จะเปิดใช้ไว้เป็นค่าเริ่มต้น ส่วนบน Mac ต้องตั้งค่าให้ปุ่ม Option เป็น Meta จึงจะใช้งานได้
    • คำสั่ง reset หรือ stty sane ใช้กู้คืนเมื่อเทอร์มินัลเสียจากการเผลอแสดงผลไฟล์ไบนารี
    • แม้หน้าจอจะแสดงผลเพี้ยนก็ยังพิมพ์ได้อยู่ ดังนั้นให้พิมพ์ reset แล้วกด Enter เพื่อกู้คืน
    • CTRL + C / D ใช้สำหรับยกเลิกคำสั่งและส่งสัญญาณ EOF (จบไฟล์) ตามลำดับ
    • หากกด CTRL + D ตอนที่พรอมป์ต์ว่างอยู่ จะเป็นการออกจากเชลล์
    • CTRL + L ทำงานเหมือนคำสั่ง clear คือเคลียร์หน้าจอทันที
    • โดยยังคงเก็บคำสั่งที่กำลังพิมพ์ไว้และย้ายพรอมป์ต์ขึ้นไปด้านบนของหน้าจอ
    • cd - ย้ายกลับไปยังไดเรกทอรีก่อนหน้าได้ทันที ส่วน pushd / popd ใช้สแตกของไดเรกทอรีเพื่อสลับทำงานข้ามหลายตำแหน่งได้
    • > file.txt ใช้ล้างไฟล์ให้ว่างโดยไม่ลบไฟล์ จึง คงสิทธิ์และความเป็นเจ้าของเดิมไว้
    • ตัวแปร $_ ใช้ อาร์กิวเมนต์ตัวสุดท้ายของคำสั่งก่อนหน้า ซ้ำได้
    • ตัวอย่าง: mkdir -p /path/newdir && cd "$_"
    • set -e, set -u เป็นออปชันที่ช่วยเพิ่มความปลอดภัยให้สคริปต์
    • set -e จะออกทันทีเมื่อเกิดข้อผิดพลาด
    • set -u จะถือเป็นข้อผิดพลาดเมื่อมีการอ้างถึงตัวแปรที่ยังไม่ได้กำหนด
    • ชุด set -euo pipefail ให้การป้องกันที่เข้มขึ้นยิ่งกว่าเดิม

คีย์ลัดและความสามารถขั้นสูงใน Bash และ Zsh

  • CTRL + R ใช้ค้นหาแบบเพิ่มผลลัพธ์ย้อนกลับในประวัติคำสั่ง
    • เมื่อพิมพ์คีย์เวิร์ดก็จะค้นหาคำสั่งเก่าและนำกลับมาใช้ซ้ำได้ทันที
  • !! ใช้รันคำสั่งก่อนหน้าทั้งหมดอีกครั้ง
    • สามารถใช้ sudo !! เพื่อรันคำสั่งก่อนหน้าซ้ำด้วยสิทธิ์ผู้ดูแลระบบได้
  • CTRL + X, CTRL + E ใช้เปิดคำสั่งที่กำลังพิมพ์อยู่ใน ตัวแก้ไขข้อความหลัก (เช่น Vim, Nano) เพื่อแก้ไขแล้วค่อยรัน
    • ใน Zsh ต้องตั้งค่าเพิ่มเติมแยกต่างหาก
    • คำสั่ง fc เป็นวิธีดั้งเดิมสำหรับเปิดคำสั่งก่อนหน้าใน $EDITOR เพื่อแก้ไข
  • ESC + . หรือ ALT + . จะแทรกอาร์กิวเมนต์ตัวสุดท้ายของคำสั่งล่าสุดลงที่ตำแหน่งเคอร์เซอร์
    • หากกดซ้ำจะวนย้อนกลับไปใช้อาร์กิวเมนต์จากคำสั่งก่อนหน้านั้นได้
    • !$ ให้ความสามารถเดียวกันในแบบไม่โต้ตอบ
  • Brace Expansion เป็นความสามารถขยายวงเล็บปีกกาที่ช่วย ลดการพิมพ์ซ้ำ

    • cp pf.conf{,.bak}cp pf.conf pf.conf.bak
    • mv filename.{txt,md}mv filename.txt filename.md
    • mkdir -p project/{src,tests,docs} ใช้สร้างหลายไดเรกทอรีพร้อมกัน
    • Process Substitution <(command) ทำให้เอาต์พุตของคำสั่งถูกใช้งานได้เหมือนเป็นไฟล์
    • ตัวอย่าง: diff <(sort file1.txt) <(sort file2.txt) ใช้เปรียบเทียบโดยไม่ต้องมีไฟล์ชั่วคราว
    • Globstar(**) ใช้ค้นหาไฟล์แบบเรียกซ้ำลงไปถึงไดเรกทอรีย่อย
    • ใน Bash ต้องเปิดใช้ด้วย shopt -s globstar ส่วนใน Zsh เปิดใช้งานมาโดยค่าเริ่มต้น
    • ตัวอย่าง: ls **/*.js ใช้ค้นหาไฟล์ JS ในทุกโฟลเดอร์ย่อย
  • ชุด CTRL + Z, bg, disown ใช้สำหรับ รันโปรเซสเบื้องหลังและแยกออกจากเชลล์

    • ใช้ CTRL + Z เพื่อพักการทำงานชั่วคราว → bg เพื่อให้ทำงานต่อในเบื้องหลัง → disown เพื่อแยกออกจากเชลล์
    • ทำให้โปรเซสทำงานต่อได้แม้จะปิด SSH ไปแล้ว
    • command |& tee file.log ใช้ส่งทั้ง เอาต์พุตมาตรฐาน (stdout) และ ข้อผิดพลาดมาตรฐาน (stderr) ผ่านไพป์พร้อมกัน
    • |& เป็นรูปย่อของ 2>&1 |
    • ใช้ tee เพื่อแสดงผลบนหน้าจอและบันทึกล็อกไปพร้อมกัน

คำแนะนำสำคัญในการใช้เชลล์

  • เชลล์คือ กล่องเครื่องมือ และถ้าใช้ได้คล่องจะช่วยเพิ่มผลิตภาพได้มาก
  • แทนที่จะพยายามจำคีย์ลัดทั้งหมดพร้อมกัน การ ค่อย ๆ ฝึกให้ติดเป็นนิสัยทีละอย่าง จะได้ผลกว่า
  • สามารถลดการพิมพ์ซ้ำและการพิมพ์ที่ไม่จำเป็น เพื่อ ทำให้โฟลว์การทำงานเรียบง่ายขึ้น
  • เมื่อคุ้นเคยแล้ว เทอร์มินัลจะไม่ใช่อุปสรรคอีกต่อไป แต่จะกลายเป็น พื้นที่ทำงานของคุณเอง

3 ความคิดเห็น

 
phoon 2026-03-30

เกือบทั้งหมดเป็นคีย์ไบน์ดิงของ emacs แต่แทบไม่ได้พูดถึง emacs เลย พอเห็นช่วงนี้มีการแชร์กันเยอะในลักษณะเป็นทิปก็รู้สึกถึงความเปลี่ยนแปลงของยุคสมัยขึ้นมา จริง ๆ แล้วไลบรารี readline นั่นแหละที่นำคีย์ไบน์ดิงแบบ emacs ไปใช้กันถ้วนหน้า ดูเหมือนว่าจะผ่านมาราว 20 ปีแล้วตั้งแต่ทุกอย่างเปลี่ยนไปเป็น IDE แต่ในมุมของฟอสซิลที่ยังเคยใช้พวกอย่าง gdbtui ก็ยังคิดว่า ของดีอย่างไรก็ไม่ตาย

 
GN⁺ 2026-03-27
ความเห็นจาก Hacker News
  • สิ่งที่ทำให้รู้สึกว่าเปลี่ยนชีวิตจริง ๆ คือช่วงที่ผม remap ปุ่มลูกศรขึ้น
    ตอนนี้ไม่ต้องไล่วนทุกคำสั่งอีกต่อไป แต่จะค้นหาเฉพาะคำสั่งที่ขึ้นต้นด้วยตัวอักษรที่พิมพ์ไว้แล้ว
    เช่น ถ้าพิมพ์ tar - แล้วกดลูกศรขึ้น ก็จะได้ตัวเลือก tar ที่เคยใช้ก่อนหน้านี้ขึ้นมาทันที
    ใน zsh ตั้งค่าแบบนี้

    bindkey "^[OA" up-line-or-beginning-search # Up  
    bindkey "^[OB" down-line-or-beginning-search # Down
    
    • พอเริ่มใช้ CTRL+r แล้ว คุณจะไม่กลับไปใช้ปุ่มลูกศรขึ้นอีกเลย
    • ผมคิดว่านี่คือ ตัวเปลี่ยนเกม แบบแท้จริง ถ้าอยากทำคล้ายกันใน bash ให้เพิ่มบรรทัดต่อไปนี้ใน .inputrc
      "\e[A":history-search-backward  
      "\e[B":history-search-forward
      
    • ใน fish shell นี่เป็น พฤติกรรมค่าเริ่มต้น อยู่แล้ว โดยจะไล่คำสั่งด้วยปุ่มขึ้น/ลงตามคำที่พิมพ์ไว้ และยังใช้ alt+ขึ้น/ลง เพื่อไล่เฉพาะอาร์กิวเมนต์ได้ด้วย
    • ทำแบบเดียวกันนี้ได้ใน .inputrc เช่นกัน
    • ของผมจะคงปุ่มลูกศรขึ้น/ลงไว้เหมือนเดิม แล้วไปตั้ง ctrl+p กับ ctrl+n ให้ทำงานแบบนี้แทน
  • การเปิด vim-mode ในเทอร์มินัลทำให้ใช้งานสบายขึ้นมาก
    พิมพ์ผิดเมื่อสามคำก่อนหน้านี้เหรอ? ใช้ 3bcw จบเลย
    ลบทั้งบรรทัดใช้ cc ส่วนแก้ไขที่ซับซ้อนก็กด v เพื่อเปิดใน (neo)vim ได้ทันที
    ถ้าใช้ (neo)vim อยู่แล้ว นี่เยี่ยมมากเพราะไม่ต้องจำคีย์ลัดชุดใหม่

    • ผมนึกถึงข้อความตอนหนึ่งในคู่มือ Emacs สมัยก่อน แทนที่จะใช้คำสั่งซับซ้อน ผมอยากแนะนำ การตั้งค่าเมาส์ มากกว่า
    • ผมใช้ (n)vim มาเกิน 20 ปีแล้ว แต่ไม่ชอบ vi-mode ใน shell ถ้าต้องใช้คำสั่งซับซ้อน การกด ctrl-x+e เพื่อเปิดใน neovim ถือเป็น จุดกึ่งกลางที่ดี
    • ผมก็ใช้ vim บ่อย แต่ไม่ใช้ใน shell แทนที่จะนั้นผมใช้ คีย์ลัดสไตล์ Emacs (ctrl-a, ctrl-e ฯลฯ) ทั่วทั้ง macOS และคิดว่าอยากให้ vim รองรับ emacs binding ใน insert mode
    • เพิ่งรู้เป็นครั้งแรกว่าฟีเจอร์นี้ชื่อว่า “readline vi-mode” ต้องไปหาข้อมูลเพิ่มแล้ว
    • ผมไม่เข้าใจว่าทำไม emacs mode ถึงเป็นค่าเริ่มต้น ทุกครั้งที่เปิด shell ใหม่ สิ่งแรกที่ผมพิมพ์คือ set -o vi
  • ผมประทับใจที่มีคนเอาสคริปต์ชื่อ \# ไปใส่ไว้ใน PATH เพื่อให้ คอมเมนต์บางส่วนของ pipeline ได้

    #!/bin/sh
    cat
    
    • ผมก็ใช้ทริกคล้าย ๆ กัน โดยมีไฟล์ ~/bin/noglob เป็น
      #!/bin/sh
      $*
      
      แบบนี้เพื่อหลีกเลี่ยง การชนกันของ noglob เวลาจะเรียกสคริปต์ zsh จาก bash
    • ผมใช้วงเล็บสำหรับคอมเมนต์ เหมาะกับการทำเอกสารให้สคริปต์ แต่ใน interactive shell จะค่อนข้างยุ่งยาก ถึงอย่างนั้นก็เป็น วิธีคอมเมนต์ที่สร้างสรรค์ ดี
    • ผมสงสัยว่ามันมีข้อดีกว่า mycmd1 #| mycmd2 ยังไง
    • อันนี้มีประโยชน์จริง ๆ ผมว่าจะเพิ่มไว้ใน $PATH ของตัวเอง
  • ปกติ CTRL+W จะลบย้อนกลับไปจนถึงช่องว่างก่อนหน้า เลยลบ /var/log/nginx/ ทั้งก้อนได้
    ส่วน Alt+Backspace จะลบย้อนกลับไปจนถึงอักขระที่ไม่ใช่ตัวอักษร
    แต่ต้องระวังเพราะมันไปชนกับ คีย์ลัดปิดแท็บในเบราว์เซอร์

    • ตั้งแต่ Firefox v147 เป็นต้นมา มีฟังก์ชัน override คีย์ลัดเพิ่มเข้ามาแล้ว ลิงก์ที่เกี่ยวข้อง
    • บน macOS ไม่มีปัญหานี้ เพราะคีย์ลัดของ GUI กับของเทอร์มินัลแยกกันอยู่ ⌘C, ⌘W ฯลฯ ก็ยังทำงานแบบเดิมในเทอร์มินัล
    • ในสภาพแวดล้อมของผม (fish + Alacritty) มันทำงานกลับกัน แต่ก็ยังดีที่ใช้ Ctrl-Shift-T เพื่อกู้แท็บที่ปิดไปแล้วได้
    • ถ้าเอา / ออกจากการตั้งค่า $WORDCHARS ก็จะได้พฤติกรรมตามที่ต้องการ (ลิงก์อ้างอิง)
    • ใช้ Ctrl-Shift-T กู้แท็บกลับมาได้ทันที
  • แนะนำให้อัปเกรด การค้นหา history ด้วย fzf shell integration
    วิดีโอสาธิต / เอกสารทางการ

  • ผมมีทริกที่ใช้บ่อยอยู่ข้อหนึ่ง
    เวลาเขียนคำสั่งยาว ๆ แล้วต้องไปทำอย่างอื่นก่อน ผมจะไม่ Ctrl-C ยกเลิก แต่จะ คอมเมนต์ไว้แล้วรัน เพื่อเก็บไว้ใน history

    $ long_command  
    $ #long_command  
    $ stuff_1  
    $ stuff_2  
    $ #long_command  
    $ long_command
    
    • ใน zsh ทำได้ด้วยการ bind "push-line-or-edit" ส่วนใน bash ก็เลียนแบบได้คล้ายกันด้วย C-u แล้วตามด้วย C-y
    • วิธีที่ง่ายกว่าคือใช้ ctrl-u เพื่อบันทึกและล้างบรรทัดปัจจุบัน จากนั้นใช้ ctrl-y วางกลับมาใหม่ ใน zsh ใช้ alt-q เพื่อทำขั้นตอนนี้ให้อัตโนมัติได้
    • ใน bash ใช้ alt-shift-3 เพื่อใส่ # ไว้หน้าคำสั่งปัจจุบันแล้วเลื่อนไปบรรทัดใหม่ได้
  • ผมไม่ค่อยชอบชื่อเรื่องสไตล์ LLM แต่บางทิปก็มีประโยชน์และน่าจะลองใช้ดู
    น่าเสียดายที่ brace expansion เข้ากับ tab completion ได้ไม่ค่อยดี อยากให้มีฟีเจอร์อย่างการคัดลอก token สุดท้ายหรือลบนามสกุลไฟล์เพิ่มด้วย

    • สำนวนการเขียนของบทความเองก็มีกลิ่น LLM เหมือนกัน เช่นประโยค “The shell is a toolbox, not an obstacle course.”
    • ใน PowerShell ก็มี readline mode เหมือนกัน ทำให้ตอนสลับใช้คู่กับ WSL ไม่รู้สึกสะดุดมาก
    • readline ทำงานเหมือนเป็นส่วนหนึ่งของ bash อยู่แล้ว เพราะงั้นจะเรียกทิปพวกนี้ว่าเป็นฟีเจอร์ของ shell ก็ถือว่าไม่ผิด
  • ผมใช้ฟังก์ชันใน zsh config สำหรับ ไม่บันทึกบางคำสั่งลง history
    เช่นจะได้ไม่เก็บคำสั่งเสี่ยง ๆ อย่าง --force ไว้ใน history

    function zshaddhistory() {
      emulate -L zsh
      if ! [[ "$1" =~ "(^ |--force|whatever)" ]] ; then
        print -sr -- "${1%%$'\n'}"
        fc -p
      else
        return 1
      fi
    }
    
    • ผมก็ทำคล้ายกัน โดยสร้าง alias ที่เติมช่องว่างนำหน้า สำหรับคำสั่งที่ไม่อยากบันทึก
      unhist () { alias $1=" $1"; }
      unhist unhist
      unhist fzf
      unhist rghist
      
  • ผมใช้สคริปต์ snippet ใน zsh สำหรับ ขยาย global alias อัตโนมัติ
    เช่นถ้าตั้ง alias -G G='rg -s' ไว้ เวลาพิมพ์ command | G ระบบก็จะขยายเป็น command | rg -s ให้อัตโนมัติ
    มันจะขยายอัตโนมัติเมื่อกด space และถ้าพิมพ์ \alias ก็จะข้ามการขยายได้

  • ใน .bashrc ของผมมีฟังก์ชัน “deep cd”
    มันจะย้ายไปยังไดเรกทอรีแรกที่มีสตริงตามอาร์กิวเมนต์ที่ส่งมาโดยอัตโนมัติ

    dcd() {
      [ -z "$1" ] && return
      local dir
      dir=$(find . -type d -path "*$1*" -print -quit 2>/dev/null)
      [ -n "$dir" ] && cd "$dir"
    }
    

    ตอนแรกคิดว่าน่าจะช้า แต่กลับกลายเป็นว่า ได้ใช้บ่อยอย่างไม่น่าเชื่อ

    • ลองดู เครื่องมือ cd อัจฉริยะ อย่าง autojump jc, z หรือ fzf เพิ่มเติมด้วยก็ดี
 
phoon 2026-03-30

การรีแมปปิงปุ่มลูกศรขึ้นด้านบนแบบข้างบน ผู้ใช้ Emacs ก็แค่ใช้ c-r กันอยู่แล้ว ท้ายที่สุดของการจูนก็คือค่าดั้งเดิม.