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

มาสเตอร์ Command Line: คู่มือสำหรับผู้เริ่มต้น สู่ Terminal Mastery

สวัสดีครับทุกคน! ในบทความนี้เราจะมาดู command line (รู้จักอีกชื่อว่า CLI, console, terminal หรือ shell) กันดีๆ

Command line เป็นหนึ่งใน tools ที่ useful และ efficient ที่สุดที่เรามีในฐานะ developers และ computer users โดยทั่วไป แตการใช้งานอาจรู้สึก overwhelming และ complex ตอนเริ่มต้น

ในบทความนี้ผมจะพยายามอธิบายส่วนประกอบของ command line interface และ basics ของการทำงาน ให้เข้าใจง่าย ที่สุด เพื่อคุณเริ่มใช้มันสำหรับ daily tasks ได้

Let's go! =D

Table of Contents

  • ความแตกต่างระหว่าง console, terminal, command line (CLI) และ Shell
    • Console
    • Terminal
    • Shell
    • Command line (CLI)
  • ทำไมต้องใช้ terminal?
  • ชนิดของ shells ต่างๆ
    • ประวัติสั้นๆ - Posix
    • รู้ไหมว่าตัวเองรัน shell อะไรอยู่?
    • Shell ไหนดีกว่า?
      • ความคิดเห็นเกี่ยว customization
  • คำสั่ง common และ useful ที่สุด
    • Git commands
  • Script แรกของเรา
  • Round up

ความแตกต่างระหว่าง console, command line (CLI), terminal และ Shell

จุดเริ่มต้นที่ดีคือรู้จัก command line จริงๆ

เวลาพูดถึงเรื่องนี้ คุณอาจเคยได้ยิน Terminal, console, command line, CLI, และ shell บ่อยครั้งคนใช้คำเหล่านี้แทนกันได้ แต่ความจริงคือมันต่างกัน

การแยกแยะแต่ละอย่างไม่จำเป็นต้องรู้ครับ แต่จะช่วยให้ชัดเจนขึ้น มาอธิบายสั้นๆ กัน

Console:

Console คือ physical device ที่ให้คุณ interact กับคอมพิวเตอร์

พูดง่ายๆ คือ หน้าจอ คีย์บอร์ด และ เมาส์ ของคุณ ในฐานะ user คุณ interact กับคอมพิวเตอร์ ผ่าน console

มาสเตอร์ Command Line: คู่มือสำหรับผู้เริ่มต้น สู่ Terminal Mastery

Terminal:

Terminal คือ text input และ output environment เป็น program ที่ทำหน้าที่ wrapper ให้เราพิมพ์คำสั่งที่คอมพิวเตอร์ process

พูดง่ายๆ คือ "หน้าต่าง" ที่คุณพิมพ์คำสั่งจริงๆ ที่คอมพิวเตอร์จะ process

มาสเตอร์ Command Line: คู่มือสำหรับผู้เริ่มต้น สู่ Terminal Mastery

จำไว้ terminal เป็น program เหมือน program อื่นๆ สามารถ install และ uninstall ได้ และมีหลาย terminals ติดตั้งพร้อมกันได้ รันตัวไหนก็ได้เมื่อไหร่ก็ได้

OS ทุกตัวมาพร้อม default terminal แต่มี options เยอะมาก เลือกได้ แต่ละตัวมี functionalities และ features ต่างกัน

Shell:

Shell คือ program ที่ทำหน้าที่ command-line interpreter มัน process commands และ output results interpret และ process คำสั่งที่ user พิมพ์

เหมือน terminal shell เป็น program ที่มาพร้อม OS ทุกตัว แต่ user install/uninstall ได้

Shells ต่างๆ มาพร้อม syntax และ characteristics ต่างกัน ก็สามารถมีหลาย shells ติดตั้งพร้อมกันได้ รันตัวไหนก็ได้เมื่อไหร่ก็ได้

ใน Linux และ Mac ส่วนใหญ่ default shell คือ Bash ใน Windows คือ Powershell Shells อื่นๆ ได้แก่ Zsh และ Fish

Shells ทำงานเป็น programming languages ด้วย เพราะเราสร้าง scripts ให้คอมพิวเตอร์ execute task ได้ Scripts คือ series ของ instructions (commands) ที่ save ไว้ในไฟล์ และ execute ภายหลังได้

เราจะมาดู scripts ภายหลัง ตอนนี้จำไว้ว่า shell คือ program ที่คอมพิวเตอร์ใช้ "เข้าใจ" และ execute คำสั่งของคุณ และคุณสามารถเขียนโปรแกรม tasks ได้อีกด้วย

จำไว้ด้วยว่า terminal คือ program ที่ shell จะรันอยู่ แต่ทั้งสองเป็น independent programs หมายถึง ใส่ shell ไหนก็ได้บน terminal ไหนก็ได้ ไม่มี dependence ระหว่างกันในมุมนี้

Command line หรือ CLI (command line interface):

CLI คือ interface ที่เราพิมพ์คำสั่งให้คอมพิวเตอร์ process พูดง่ายๆ คือ พื้นที่ที่คุณพิมพ์คำสั่งที่คอมพิวเตอร์จะ process

มาสเตอร์ Command Line: คู่มือสำหรับผู้เริ่มต้น สู่ Terminal Mastery

นี่ practically same as terminal และในความคิดเห็นของผม 2 คำนี้ใช้แทนกันได้

หนึ่งอย่างน่าสนใจ: OS ส่วนใหญ่มี 2 ประเภท interfaces:

  • CLI รับ commands เป็น inputs ให้คอมพิวเตอร์ execute tasks
  • GUI (graphical user interface) user เห็นบนหน้าจอ click แล้วคอมพิวเตอร์ respond ด้วย task ที่ตรงกัน

ทำไมต้องใช้ terminal?

เราบอกว่า OS ส่วนใหญ่มาพร้อม GUI ถ้าเราเห็นของบนหน้าจอ click around ทำอะไรก็ได้ ทำไมต้องเรียน terminal/cli/shell ที่ซับซ้อนนี้?

เหตุผลแรก: หลาย tasks มัน มีประสิทธิภาพมากกว่า จะเห็นตัวอย่างในลำดับ แต่หลาย tasks GUI ต้อง clicks หลายครั้งข้าม windows แต CLI รันคำสั่งเดียวจบ

ในความหมายนี้ การคุ้นเคยกับ command line ช่วยประหยัดเวลา และ execute tasks เร็วขึ้น

เหตุผลที่สอง: ด้วย commands คุณ automate tasks ได้ง่าย ตามที่บอก scripts สร้างได้กับ shell และ execute ภายหลังเมื่อไหร่ก็ได้ useful มากสำหรับ repetitive tasks ที่ไม่อยากทำซ้ำ

ตัวอย่าง: script สร้าง online repo ใหม่ ให้ หรือสร้าง infrastructure บน cloud provider หรือ task ง่ายๆ เปลี่ยน wallpaper ทุกชั่วโมง

Scripting ประหยัดเวลามากกับ repetitive tasks

เหตุผลที่สาม: บางครั้ง CLI เป็น วิธีเดียว ที่ interact กับคอมพิวเตอร์ได้ เช่น interact กับ cloud platform server บanyakanไม่มี GUI ให้ มีแค่ CLI รันคำสั่ง

ดังนั้น คุ้นเคย CLI = interact กับคอมพิวเตอร์ได้ทุกโอกาส

เหตุผลสุดท้าย: ดู cool และสนุก ไม่เห็น movie hackers คลิกคอมพิวเตอร์หรอกนะ ;)

ชนิดของ Shells ต่างๆ

ก่อนลงลึกลงคำสั่งจริง ควร recognize shells ต่างๆ และ identify ว่าตัวเองรัน shell อะไรอยู่

Shells ต่างๆ มาพร้อม syntax และ features ต่างกัน เพื่อรู้คำสั่งที่ถูกต้อง ต้องรู้ก่อนว่ารัน shell อะไรอยู่

ประวัติสั้นๆ – Posix

สำหรับ shells มี common standard เรียกว่า Posix

Posix ทำงานกับ shells คล้าย ECMAScript กับ JavaScript เป็น standard ที่ dictate characteristics และ features ที่ shells ทุกตัวควร comply

Standard นี้ established ใน 1980s และ most current shells developed ตาม standard นั้น นั่นคือเหตุผลที่ most shells share similar syntax และ features

รู้ไหมว่าตัวเองรัน shell อะไรอยู่?

รู้ได้ง่าย: เปิด terminal พิมพ์ echo $0 จะ print current running program name ซึ่งในกรณีนี้คือ shell จริงๆ

มาสเตอร์ Command Line: คู่มือสำหรับผู้เริ่มต้น สู่ Terminal Mastery

Shell ไหนดีกว่า?

ไม่มีความแตกต่างเยอะระหว่าง most shells เนื่องจาก comply กับ standard เดียวกัน ทำให้ทำงานคล้ายกัน

แตมี slight differences ที่อาจอยากรู้:

  • Bash ใช้กันกว้างที่สุด มาพร้อม default บน Mac และ Linux
  • Zsh คล้าย Bash แต่มาหลังและมี improvements บางอย่าง ถ้าอยากรู้รายละเอียด มี article น่าสนใจ
  • Fish shell อีกตัวที่นิยม มาพร้อม built-in features และ configurations ดีๆ เช่น autocompletion และ syntax highlighting แต่ Fish ไม่ Posix compliant ในขณะที่ Bash และ Zsh compliant นั่นหมายถึงบางคำสั่งรันบน Bash/Zsh ไม่รันบน Fish และ vice versa ทำให้ Fish scripting less compatible กับคอมพิวเตอร์ส่วนใหญ่
  • Shells อื่นๆ เช่น Ash หรือ Dash (ชื่อทำให้สับสนมาก...) เป็น stripped-down versions ของ Posix shells ให้แค่ features ที่ Posix ต้องการ ไม่มีเพิ่ม ในขณะที่ Bash และ Zsh เพิ่ม features มากกว่า Posix

การที่ shells เพิ่ม features ทำให้ interact ง่ายและ friendly แต่ execute scripts และ commands ช้ากว่า

Common practice: ใช้ "enhanced" shells เช่น Bash หรือ Zsh สำหรับ general interaction และ "stripped" shell เช่น Ash หรือ Dash สำหรับ execute scripts

ตอน scripting จะเห็นวิธี define ว่า shell ไหน run script ไหน

อยากเปรียบเทียบ shells เหล่านี้ละเอียด มี video อธิบายดีมาก

ถ้าต้องแนะนำ ผมแนะนำ bash เพราะมัน standard และ commonly-used ที่สุด คุณจะนำความรู้ไปใช้ใน most environments ได้

แต่ความจริง ไม่มีความแตกต่างมากระหว่าง most shells ลองหลายตัว ดูว่าชอบตัวไหน ;)

ความคิดเห็นเกี่ยว customization

บอกไปว่า Fish มาพร้อม built-in config เช่น autocompletion และ syntax highlighting มัน built-in ใน Fish แตใน Bash หรือ Zsh คุณ config features เหล่านี้ได้เช่นกัน

จุดคือ shells customizable ได้ คุณ edit ได้ว่า program ทำงานอย่างไร คำสั่งไหน available prompt แสดงข้อมูลอะไร และอื่นๆ

เราจะไม่เจาะลึก customization options ตรงนี้ แต่รู้ว่าตอน install shell บนคอมพิวเตอร์ ไฟล์บางไฟล์จะถูกสร้างบนระบบ ภายหลัง edit ไฟล์เหล่านั้น customize program ได้

ยังมี plugins ออนไลน์เยอะ customize shell แบบง่าย ติดตั้ง แล้วได้ features ที่ plugin ให้ เช่น OhMyZsh และ Starship

Customization options เหล่านี้จริงสำหรับ Terminals ด้วย

ไม่ได้แค่หลาย shell และ terminal options เลือก – แต่ละ option ยัง customize ได้อีกด้วย

ตอนเริ่มต้น ข้อมูลเยอะนี้อาจ overwhelming แต่รู้แค่ว่ามี options เยอะ และแต่ละอัน customize ได้ แค่นั้นเอง

คำสั่ง Common และ Useful ที่สุด

ตอนนี้มี foundation ของ CLI แล้ว มาลงลึกลง most useful commands สำหรับ daily tasks

จำไว้ว่า examples นี้ based on current config ของผม (Bash on Linux OS) แต่ most commands ควร apply กับ most configs ได้

  • Echo พิมพ์ใน terminal parameter ที่ส่งเข้าไป
echo Hello freeCodeCamp! // Output: Hello freeCodeCamp! 
  • pwd = print working directory พิมพ์ "ที่" หรือ directory ปัจจุบัน
pwd // Output: /home/German 
  • ls แสดง contents ของ directory ปัจจุบัน แสดงทั้ง files และ directories

ตัวอย่าง ผมอยู่ใน React project directory:

ls // Output: node_modules package.json package-lock.json public README.md src 

ส่ง flag -a จะแสดง hidden files/directories เช่น .git หรือ .gitignore

ls -a // Output: . .env .gitignore package.json public src .. .git node_modules package-lock.json README.md 
  • cd = Change directory ย้ายจาก current directory ไปอีกที่

อยู่ home directory พิมพ์ cd Desktop ไป Desktop Directory

อยากขึ้นหนึ่ง level (ไป directory ที่ contain current directory) พิมพ์ cd ..

พิมพ์ cd เดี่ยว ไป home directory ทันที

  • mkdir = make directory สร้าง directory ใหม่ ส่ง parameter ชื่อ directory

อยากสร้าง directory ชื่อ "Test" พิมพ์ mkdir test

  • rmdir = Remove directory ลบ directory ต้องการ parameter ชื่อ directory เหมือน mkdir: rmdir test
  • touch สร้าง empty file ใน current directory Parameter: file name เช่น touch test.txt
  • rm ลบ files เหมือน rmdir ลบ directories: rm test.txt
  • cp copy files หรือ directories รับ 2 parameters: ไฟล์/โฟลเดอร์ที่ copy และ destination (copy ไปที่ไหน)

อยาก copy txt file ใน directory เดียวกัน:

cp test.txt testCopy.txt 

directory ไม่เปลี่ยน เพราะ destination ใส่ชื่อไฟล์ใหม่

อยาก copy ไป different directory แต่เก็บชื่อไฟล์เดิม:

cp test.txt ./testFolder/ 

อยาก copy ไป different folder เปลี่ยนชื่อไฟล์:

cp test.txt ./testFolder/testCopy.txt 
  • mv = move ย้าย file หรือ directory จากที่หนึ่งไปอีกที่ (สร้างใหม่ ลบเก่า เหมือน cut และ paste)

รับ 2 parameters: file/directory ที่ย้าย และ destination

mv test.txt ./testFolder/ 

เปลี่ยนชื่อไฟล์พร้อมกันได้:

mv test.txt ./testFolder/testCopy.txt 
  • head ดูส่วนต้นของไฟล์หรือ piped data จาก terminal
head test.txt // Output: this is the beginning of my test file 
  • tail เหมือนกันแต่นำท้ายไฟล์
tail test.txt // Output: this is the end of my test file 
  • --help flag ใช้กับ most commands ได้ จะ return info ว่าใช้ command นั้นอย่างไร
cd --help // output: cd: cd [-L|[-P [-e]] [-@]] [dir] Change the shell working directory. 

Change current directory ไป DIR Default DIR คือ value ของ HOME shell variable

Variable CDPATH define search path สำหรับ directory containing DIR Alternative directory names ใน CDPATH separated by colon :

Null directory name = current directory ถ้า DIR เริ่มด้วย ...

  • man command return info เกี่ยวกับคำสั่งไหนก็ได้
 man cp // output: CP(1) User Commands CP(1) NAME cp - copy files and directories SYNOPSIS cp [OPTION]... [-T] SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY cp [OPTION]... -t DIRECTORY SOURCE... DESCRIPTION Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. Mandatory arguments to long options are mandatory for short options too. -a, --archive same as -dR --preserve=all --attributes-only don't copy the file data, just the attributes ... 

พิมพ์ man bash ได้ manual ใหญ่เกี่ยว shell นี้ทั้งหมด ;)

  • code เปิด default code editor พิมพ์คำสั่งเดี่ยว เปิด editor พร้อม latest file/directory ที่เปิดล่าสุด

เปิดไฟล์เฉพาะ ส่ง parameter: code test.txt

เปิดไฟล์ใหม่ ส่งชื่อไฟล์ใหม่: code thisIsAJsFile.js

  • edit เปิด text files บน default command line text editor (Mac/Linux น่าจะเป็น Nano หรือ Vim)

เปิดไฟล์แล้วออกไม่ได้ หา meme นี้ก่อน:

![vimExit](https://www.freecodecamp.org/news/content/images/2022/03/vimExit.png) 

พิมพ์ :q! แล้ว enter

Meme ตลกเพราะทุกคน struggle กับ CLI text editors ตอนแรก เพราะ actions (รวม exit) ทำด้วย keyboard shortcuts การใช้ editors เรื่องใหญ่ ไปหา tutorials สนใจ ;)

  • ctrl+c ออกจาก current process ที่ terminal รันอยู่ เช่น สร้าง react app ด้วย npx create-react-app อยาก cancel build กด ctrl+c จบ
  • Copy text จาก terminal: ctrl+shift+c Paste: ctrl+shift+v
  • clear ล้าง terminal จากเนื้อหาเก่า
  • exit ปิด terminal (ไม่ใช่คำสั่งแต่น่าสนใจ) ctrl+alt+t เปิด terminal ใหม่
  • กด up/down keys navigate previous commands
  • กด tab autocomplete จาก text ที่พิมพ์ไปแล้ว กด tab twice ได้ suggestions

เช่น พิมพ์ edit test tab twice ได้ testFolder/ test.txt พิมพ์ edit test. กด tab autocomplete เป็น edit test.txt

Git commands

นอกจากจัดการ file system และ install/uninstall การ interact กับ Git และ online repos น่าจะ common ที่สุดสำหรับ developer

ทำจาก terminal efficient กว่าคลิกเยอะ มาดู git commands useful ที่สุด

  • git init สร้าง local repository ใหม่
git init // output: Initialized empty Git repository in /home/German/Desktop/testFolder/.git/ 
  • git add เพิ่มไฟล์หนึ่งหรือหลายไฟล์ไป staging ระบุไฟล์เฉพาะ หรือ all changed files ด้วย git add .
  • git commit commit changes ไป repository ต้องมี flag -m และ commit message เสมอ
git commit -m 'This is a test commit' // output: [master (root-commit) 6101dfe] This is a test commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test.js 
  • git status บอก branch ปัจจุบัน และว่ามี changes ที่ commit หรือไม่
git status // output: On branch master nothing to commit, working tree clean 
  • git clone clone (copy) repository มาใน current directory จำได้ว่า clone ทั้ง remote repos (GitHub, GitLab) และ local repos (เก็บในคอมพิวเตอร์)
git clone https://github.com/coccagerman/MazeGenerator.git // output: Cloning into 'MazeGenerator'... remote: Enumerating objects: 15, done. remote: Counting objects: 100% (15/15), done. remote: Compressing objects: 100% (15/15), done. remote: Total 15 (delta 1), reused 11 (delta 0), pack-reused 0 Unpacking objects: 100% (15/15), done. 
  • git remote add origin ระบุ URL ของ remote repository สำหรับโปรเจกต์ ถ้าอยากเปลี่ยนใช้ git remote set-url origin
git remote add origin https://github.com/coccagerman/testRepo.git 

จำได้ว่า ต้องสร้าง remote repo ก่อนเพื่อได้ URL จะดูวิธีสร้างจาก command line ด้วย script ภายหลัง ;)

  • git remote -v list current remote repository
git remote -v // output: origin https://github.com/coccagerman/testRepo.git (fetch) origin https://github.com/coccagerman/testRepo.git (push) 
  • git push upload committed changes ไป remote repo
git push // output: Counting objects: 2, done. Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (2/2), 266 bytes | 266.00 KiB/s, done. Total 2 (delta 0), reused 0 (delta 0) 
  • git branch list branches ทั้งหมด และบอก current branch สร้าง branch ใหม่ เพิ่ม parameter ชื่อ branch: git branch <branch name>
git branch // output: * main 
  • git checkout ย้าย branch ไปอีก branch รับ destination branch เป็น parameter
git checkout newBranch // output: Switched to branch 'newBranch' 
  • git pull pull (download) code จาก remote repo combine กับ local repo useful ตอน work in teams หลาย devs งาน code base เดียว แต่ละคน pull periodically เพื่อ code base ที่รวม changes จาก devs อื่นๆ

ถ้ามี code ใหม่ใน remote repo command จะ return actual files ที่ modified ใน pull ถ้าไม่มี ได้ Already up to date

git pull // output: Already up to date. 
  • git diff ดู differences ระหว่าง current branch และอีก branch
git diff newBranch // output: diff --git a/newFileInNewBranch.js b/newFileInNewBranch.js deleted file mode 100644 index e69de29..0000000 

Side comment: เปรียบเทียบ differences ระหว่าง branches/repos มักใช้ visual tools เช่น Meld ไม่ได้ว่า visualize ตรงใน terminal ไม่ได้ แต่ tools นี้ clearer visualization

  • git merge merge (combine) current branch กับอีก branch จำได้ว่า changes incorporated เฉพาะ current branch ไม่ใช่อีกอัน
git merge newBranch // output: Updating f15cf51..3a3d62f Fast-forward newFileInNewBranch.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 newFileInNewBranch.js 
  • git log list previous commits ทั้งหมดใน repo
git log // output: commit 3a3d62fe7cea7c09403c048e971a5172459d0948 (HEAD -> main, tag: TestTag, origin/main, newBranch) Author: German Cocca <german.cocca@avature.net> Date: Fri Apr 1 18:48:20 2022 -0300 Added new file commit f15cf515dd3ec398210108dce092debf26ff9e12 Author: German Cocca <german.cocca@avature.net> ... 
  • --help flag แสดง info เกี่ยวคำสั่ง เหมือน bash
git diff --help // output: GIT-DIFF(1) Git Manual GIT-DIFF(1) NAME git-diff - Show changes between commits, commit and working tree, etc SYNOPSIS git diff [options] [<commit>] [--] [<path>...] git diff [options] --cached [<commit>] [--] [<path>...] ... 

Script แรกของเรา

พร้อมสำหรับส่วนสนุกและ awesome ของ command line: scripting!

เหมือนที่บอก script คือ series ของ commands หรือ instructions ที่ execute ได้เวลาไหนก็ได้ เพื่ออธิบายวิธีเขียน ใช้ตัวอย่างง่ายๆ สร้าง github repo ด้วยคำสั่งเดียว ;)

  • สร้างไฟล์ .sh ใส่ที่ไหนก็ได้ ผมตั้งชื่อ newGhRepo.sh
  • เปิดใน text/code editor ที่ชอบ
  • บรรทัดแรกเขียน: #! /bin/sh

เรียกว่า shebang ฟังก์ชัน declare shell ที่จะ run script นี้

จำได้ว่าเคยบอกว่าใช้ shell ตัวหนึ่ง general interaction และอีกตัว execute script? Shebang คือ instruction ที่ dictate ว่า shell ไหน run script

เหมือนที่บอก ใช้ "stripped down" shell (sh shells) รัน scripts เพราะ efficient กว่า (ความแตกต่างอาจ unnoticeable แต่มากกว่า personal preference) ในเครื่องผมมี dash เป็น sh shell

ถ้าอยากให้ script รันกับ bash shebang จะเป็น #! /bin/bash

  • บรรทัดต่อไป: repoName=$1

declare variable ชื่อ repoName assign ค่า parameter ตัวแรกที่ script รับ

Parameter คือชุด characters ที่พิมพ์หลัง script/command เหมือน cd ต้องระบุ directory parameter (เช่น cd testFolder)

Identify parameters ใน script 用 dollar sign และ order ที่ parameter คาดหวัง

คาดหวะหลาย parameters เขียน:

paramOne=$1 paramTwo=$2 paramThree=$3 ... 
  • คาดหวัง repo name เป็น parameter แต่ถ้า user ลืมพิมพ์? ต้อง plan ไว้ conditional ที่ถาม user เรื่อยๆ จนกว่าจะได้ parameter

ทำได้แบบนี้:

while [ -z "$repoName" ] do echo 'Provide a repository name' read -r -p $'Repository name:' repoName done 

สิ่งที่ทำ:

  1. While repoName variable ไม่ได้ assign (while [ -z "$repoName" ])
  2. พิมพ์ข้อความนี้ (echo 'Provide a repository name')
  3. อ่าน input จาก user assign ให้ repoName variable (read -r -p $'Repository name:' repoName)
  • ตอนนี้มี repo name แล้ว สร้าง local Git repo:
echo "# $repoName" >> README.md git init git add . git commit -m "First commit" 

สร้าง readme file เขียนบรรทัดเดียว repo name (echo "# $repoName" >> README.md) แล้ว init git repo และ first commit

  • Upload repo ไป github ใช้ GitHub API:

curl -u coccagerman https://api.github.com/user/repos -d '{"name": "'"$repoName"'", "private":false}'

curl command transfer data to/from server ใช้ protocols หลายอย่าง

Flag -u declare user สร้าง repo (-u coccagerman)

Endpoint จาก GitHub API (https://api.github.com/user/repos)

Flag -d ส่ง parameters ไป command นี้ ระบุ repository name (ใช้ repoName variable) และ private = false เพราะอยาก public

Config options อื่นๆ มากใน API ดู docs

  • หลังรันคำสั่ง GitHub จะ prompt ให้พิมพ์ private token authentication

ยังไม่มี private token สร้างได้ใน GitHub: Settings > Developer settings > Personal access tokens

มาสเตอร์ Command Line: คู่มือสำหรับผู้เริ่มต้น สู่ Terminal Mastery มาสเตอร์ Command Line: คู่มือสำหรับผู้เริ่มต้น สู่ Terminal Mastery มาสเตอร์ Command Line: คู่มือสำหรับผู้เริ่มต้น สู่ Terminal Mastery
  • เกือบเสร็จ! ตอนนี้ต้องการ remote URL ของ GitHub repo ที่เพิ่งสร้าง

ได้ด้วย curl และ GitHub API อีกครั้ง:

GIT_URL=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/coccagerman/"$repoName" | jq -r '.clone_url') 

Declare variable GIT_URL assign ค่า return ของคำสั่งต่อไป

Flag -H set header ของ request

ส่ง GitHub API endpoint ควรมี username และ repo name (https://api.github.com/repos/coccagerman/"$repoName")

Pipe return value ของ request Pipe = ส่ง return value ของ process หนึ่งเป็น input ของอีก process 用 | symbol: <process1> | <process2>

รัน jq command tool สำหรับ process JSON inputs บอกให้ได้ value ของ .clone_url ซึ่งเป็น remote git URL ตาม data format ของ GitHub API

  • ขั้นตอนสุดท้าย: rename master branch เป็น main, add remote origin ที่ได้, push code ไป GitHub! =D
git branch -M main git remote add origin $GIT_URL git push -u origin main 

Full script ควรเป็นแบบนี้:

#! /bin/sh repoName=$1 while [ -z "$repoName" ] do echo 'Provide a repository name' read -r -p $'Repository name:' repoName done echo "# $repoName" >> README.md git init git add . git commit -m "First commit" curl -u <yourUserName> https://api.github.com/user/repos -d '{"name": "'"$repoName"'", "private":false}' GIT_URL=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/<yourUserName>/"$repoName" | jq -r '.clone_url') git branch -M main git remote add origin $GIT_URL git push -u origin main 
  • Test script! Execute มี 2 วิธี

Option 1: พิมพ์ shell name ส่ง file เป็น parameter: dash ../ger/code/projects/scripts/newGhRepo.sh

Option 2: ทำ file executable รัน chmod u+x ../ger/code/projects/scripts/newGhRepo.sh

จากนั้นรัน file โดยตรง: ../ger/code/projects/scripts/newGhRepo.sh

เสร็จแล้ว! Script พร้อมใช้ ทุกครั้งที่ต้องการ repo ใหม่ รัน script นี้จาก directory ไหนก็ได้

แต่วิธีนี้ต้องจำ exact route ของ script directory ยุ่งยาก แล้วถ้ารัน script ด้วยคำสั่งเดียวที่เหมือนกันเสมอ ไม่สน directory ปัจจุบัน ดีกว่า?

เข้ามา bash aliases แก้ปัญหา

Aliases คือวิธี bash ให้ตั้งชื่อ exact commands ที่อยากรัน

สร้าง alias ใหม่ edit bash config files ในระบบ ไฟล์เหล่านี้ normally ใน home directory Aliases define ในไฟล์ต่างๆ (หลัก .bashrc หรือ .bash_aliases)

ผมมี .bash_aliases มาแก้กัน

  • CLI พิมพ์ cd ไป home directory
  • ls -a list all files (รวม hidden) เช็คว่ามี .bashrc หรือ .bash_aliases
  • เปิดไฟล์ด้วย text/code editor
  • เขียน alias ใหม่:
    alias newghrepo="dash /home/German/Desktop/ger/code/projects/scripts/newGhRepo.sh"

Declare alias name, actual command รัน script (newghrepo) และใน quotes define ว่า alias ทำอะไร ("dash /home/German/Desktop/ger/code/projects/scripts/newGhRepo.sh")

ส่ง absolute path ของ script เพื่อคำสั่งนี้ work เหมือนกัน ไม่สน current directory

ไม่รู้ absolute path ของ script ไปที่ script directory บน terminal พิมพ์ readlink -f newGhRepo.sh ควร return full path

  • เสร็จ edit save file restart terminal วอลล่า! ตอนนี้รัน script ด้วย newghrepo ได้เลย ไม่สน directory ปัจจุบัน เร็วมากกว่าเปิด browser click around สร้าง repo! =D

หวังว่าให้รสชาติ optimization ที่ทำได้กับ scripting ต้องการ work หน่อยตอนแรก write, test, setup script แต่หลังนั้น ไม่ต้องทำ task นั้น manually อีกเลย ;)

Round up

Terminal อาจ intimidating และ intricate ตอนเริ่มต้น แต่ worth it ที่จะ invest time และ effort เรียนรู้ ins and outs ประโยชน์ efficiency ดีเกินไปที่จะพลาด!

สนใจเรียน terminal และ Bash เพิ่ม Zach Gollwitzer มี awesome crash course series บน youtube เขายังมี tutorials เยอะ topics อื่นๆ Node, Javascript แนะนำ follow เขา ;)

เหมือนเดิม หวังว่า enjoy article และเรียนรู้ใหม่ๆ ถ้าอยาก follow ผมบน linkedin หรือ twitter ก็ได้

Cheers และเจอกันครั้งหน้า! =D

มาสเตอร์ Command Line: คู่มือสำหรับผู้เริ่มต้น สู่ Terminal Mastery