Hi everyone! Bài này chúng ta deep dive vào command line (còn gọi CLI, console, terminal hoặc shell).
Command line là một trong những tools useful và efficient nhất chúng ta có as developers và computer users nói chung. Nhưng dùng nó có thể feel overwhelming và complex khi starting out.
Bài viết sẽ simply explain các parts cấu thành command line interface, và basics cách nó works, để bạn start dùng cho daily tasks.
Let's go! =D
Table of Contents
- Khác biệt console, terminal, command line (CLI) và Shell
- Console
- Terminal
- Shell
- Command line (CLI)
- Tại sao nên care về terminal?
- Các loại shells khác nhau
- Chút history - Posix
- Làm sao biết shell nào đang chạy?
- Shell nào better?
- Comment về customization
- Most common và useful commands
- Git commands
- First script của chúng ta
- Round up
Khác biệt console, command line (CLI), terminal và Shell
Good place to start là biết exactly command line là gì.
Khi refer đến này, bạn nghe terms Terminal, console, command line, CLI, shell. Người ta thường dùng interchangeably nhưng truth là chúng actually different things.
Differentiating each không necessarily crucial knowledge, nhưng helps clarify. Briefly explain each.
Console:
Console là physical device cho phép interact với computer.
Plain English: màn hình máy tính, bàn phím, chuột. As user, bạn interact với computer through console.

Terminal:
Terminal là text input/output environment. Là program act as wrapper cho phép enter commands computer processes.
Plain English: "window" bạn enter actual commands computer sẽ process.

Terminal là program, như bất kỳ program nào. Install/uninstall as you please. Có thể nhiều terminals installed và run whichever you want.
All OSes come with default terminal, nhưng nhiều options outside với own functionalities/features.
Shell:
Shell là program act as command-line interpreter. Nó processes commands và outputs results. Interpret và process commands entered by user.
Same as terminal, shell là program default in all OSes, nhưng also install/uninstall by user.
Different shells come với different syntax và characteristics. Có thể nhiều shells installed và run each khi muốn.
Trong most Linux và Mac, default shell là Bash. Windows là Powershell. Other common shells: Zsh, Fish.
Shells cũng work as programming languages, sense rằng với chúng ta build scripts để computer execute certain task. Scripts = series of instructions (commands) save on file execute whenever.
Sẽ look at scripts later. For now nhớ shell là program computer dùng "understand" và execute commands, và bạn dùng nó program tasks.
Cũng nhớ terminal là program shell sẽ run in. But both programs independent. Nghĩa là, any shell run on any terminal. No dependence between both programs in that sense.
Command line hoặc CLI (command line interface):
CLI là interface enter commands cho computer process. Plain English: space enter commands computer sẽ process.

Practically same as terminal và opinion terms dùng interchangeably.
Interesting thing: most OSes có two interface types:
- CLI, takes commands as inputs để computer execute tasks.
- GUI (graphical user interface), user see things on screen click them computer respond executing corresponding task.
Tại sao nên care về terminal?
Vừa mention most OSes có GUI. Nếu see things on screen click around do whatever, bạn wonder why learn complicated terminal/cli/shell?
First reason: many tasks, just more efficient. Examples in a second, nhưng many tasks GUI require many clicks around different windows. CLI execute với single command.
In this sense, comfortable với command line giúp save time và execute tasks quicker.
Second reason: commands dễ automate tasks. Như mentioned, build scripts với shell execute scripts whenever. Incredibly useful repetitive tasks không want do over and over.
Examples: script tạo online repo mới, hoặc tạo infrastructure trên cloud provider, hoặc simpler task như đổi screen wallpaper mỗi giờ.
Scripting great way save time repetitive tasks.
Third reason: sometimes CLI sẽ only way interact với computer. Example: interact với cloud platform server. Most cases, no GUI available, just CLI run commands.
Comfortable với CLI allow interact với computers all occasions.
Last reason: looks cool và fun. Movie hackers không click around computers, right? ;)
Các loại shells khác nhau
Trước diving vào actual commands, important recognize different shell types và how identify shell đang chạy.
Different shells có different syntax và features, so để know exactly command enter, first need know shell running.
Chút history – Posix
Cho shells, common standard gọi Posix.
Posix works for shells similar way ECMAScript works for JavaScript. Standard dictate certain characteristics/features all shells should comply with.
Standard established 1980s và most current shells developed theo standard. That's why most shells share similar syntax/features.
Làm sao biết shell nào đang chạy?
Để biết shell currently running, mở terminal enter echo $0. In current running program name, case này là actual shell.

Shell nào better?
Không có A LOT difference giữa most shells. Vì most comply same standard, most work similarly.
Slight differences bạn might want know:
- Bash most widely used, default installed Mac và Linux.
- Zsh rất similar Bash, created after, nice improvements over it. Want more detail differences, here's cool article.
- Fish commonly used shell với nice built-in features/configs: autocompletion, syntax highlighting. Thing về Fish: not Posix compliant, Bash và Zsh are. Means some commands run trên Bash/Zsh won't run Fish và vice versa. Makes Fish scripting less compatible most computers vs Bash/Zsh.
- Other shells như Ash hoặc Dash (naming confusing...) stripped-down versions của Posix shells. Chỉ offer features required in Posix, nothing else. Bash và Zsh add more features than Posix requires.
Fact shells add features makes easier/friendlier interact, but slower execute scripts/commands.
Common practice: dùng "enhanced" shells như Bash/Zsh cho general interaction, "stripped" shell như Ash/Dash execute scripts.
Khi get to scripting, we'll see how define shell execute given script.
Interested detailed comparison shells, here's video explains really well:
Nếu recommend shell, tôi recommend bash – most standard và commonly-used. Translate knowledge into most environments.
But again, truth not A LOT difference. Try a few see which you like best. ;)
Comment về customization
Vừa mention Fish built-in config autocompletion/syntax highlighting. Comes built-in Fish, nhưng Bash/Zsh configure these features too.
Point: shells customizable. Edit how program works, commands available, info prompt shows, more.
Won't see customization options detail here, but know when install shell, certain files created on system. Later edit those files customize program.
Also, many plugins online allow customize shell easier. Install them get features plugin offers. Examples: OhMyZsh, Starship.
Customization options also true for Terminals.
So không chỉ many shell/terminal options – cũng many config options cho each shell/terminal.
Nếu starting out, info này overwhelming. But just know many options available, each customizable too. That's it.
Most common và useful commands
Now foundation CLI works, dive into most useful commands daily tasks.
Examples based on my config (Bash on Linux OS). But most commands apply most configs anyway.
- Echo prints terminal whatever parameter pass it.
echo Hello freeCodeCamp! // Output: Hello freeCodeCamp!
- pwd = print working directory, prints "place" hoặc directory currently at.
pwd // Output: /home/German
- ls presents contents directory currently in. Files và directories.
Ví dụ, tôi ở React project directory:
ls // Output: node_modules package.json package-lock.json public README.md src
Pass flag -a cũng show hidden files/directories. Như .git hoặc .gitignore
ls -a // Output: . .env .gitignore package.json public src .. .git node_modules package-lock.json README.md
- cd = Change directory, take từ current directory đến another.
Trên home directory, enter cd Desktop → Desktop Directory.
Muốn go up one directory (directory chứa current), enter cd ..
Enter cd alone → straight to home directory.
- mkdir = make directory, create new directory. Pass directory name parameter.
Tạo directory "Test": mkdir test.
- rmdir = Remove directory. Needs directory name parameter:
rmdir test. - touch tạo empty file current directory. Parameter: file name,
touch test.txt. - rm delete files, như
rmdirremove directories.rm test.txt - cp copy files/directories. Two parameters: source file/directory, destination.
Copy txt file same directory:
cp test.txt testCopy.txt
Directory không change, "destination" là new file name.
Copy vào different directory keep same name:
cp test.txt ./testFolder/
Copy different folder change file name:
cp test.txt ./testFolder/testCopy.txt
- mv = move, move file/directory từ place đến another. Create new location delete previous (like cut/paste).
Two parameters: file/directory move, destination.
mv test.txt ./testFolder/
Change name same command:
mv test.txt ./testFolder/testCopy.txt
- head view beginning of file/piped data từ terminal.
head test.txt // Output: this is the beginning of my test file
- tail same nhưng show end of file.
tail test.txt // Output: this is the end of my test file
- --help flag dùng most commands return info how use command.
cd --help // output: cd: cd [-L|[-P [-e]] [-@]] [dir] Change the shell working directory.
- man command return info about any particular command.
man cp // output: CP(1) User Commands CP(1) NAME cp - copy files and directories SYNOPSIS cp [OPTION]... [-T] SOURCE DEST ...
Enter man bash return huge manual everything about shell. ;)
- code open default code editor. Alone opens editor with latest file/directory opened.
Open given file pass parameter: code test.txt.
Open new file pass new file name: code thisIsAJsFile.js.
- edit open text files default command line text editor (Mac/Linux likely Nano hoặc Vim).
Open file can't exit editor, first look meme:

Then type :q! enter.
Meme funny vì everyone struggles CLI text editors at first, most actions (like exiting) done với keyboard shortcuts. Using editors whole other topic, go look tutorials if interested. ;)
- ctrl+c exit current process terminal running. Ví dụ creating react app
npx create-react-appcancel build, hit ctrl+c stop. - Copy text từ terminal: ctrl+shift+c, paste: ctrl+shift+v
- clear clear terminal từ all previous content.
- exit close terminal. (Not command but cool) ctrl+alt+t open new terminal.
- up/down keys navigate previous commands entered.
- tab autocomplete based on text written. tab twice suggestions based on text.
Ví dụ write edit test tab twice → testFolder/ test.txt. Write edit test. hit tab autocomplete → edit test.txt
Git commands
Besides file system và install/uninstall, interact với Git và online repos probably most common things dùng terminal as developer.
Efficient hơn từ terminal than clicking around, look at most useful git commands.
- git init create new local repository.
git init // output: Initialized empty Git repository in /home/German/Desktop/testFolder/.git/
- git add add one/more files to staging. Detail specific file hoặc add all changed files
git add . - git commit commit changes to repository. Must accompanied by
-mflag và 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 tells current branch và whether changes to commit.
git status // output: On branch master nothing to commit, working tree clean
- git clone clone (copy) repository vào current directory. Clone both remote (GitHub, GitLab) và local repositories.
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 detail URL remote repository cho project. Change later:
git remote set-url origin.
git remote add origin https://github.com/coccagerman/testRepo.git
Lưu ý cần create remote repo first để get URL. Sẽ see how từ command line với script later. ;)
- 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 to 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 all available branches và tells current branch. Create new branch: add branch name parameter
git branch <branch name>.
git branch // output: * main
- git checkout move từ branch này sang branch khác. Takes destination branch parameter.
git checkout newBranch // output: Switched to branch 'newBranch'
- git pull pull (download) code từ remote repo combine với local repo. Useful working in teams, nhiều developers same code base. Each developer periodically pulls từ remote repo work in code base includes changes done by all other devs.
Nếu new code in remote repo, command return actual files modified in pull. Nếu không, Already up to date.
git pull // output: Already up to date.
- git diff view differences giữa current branch và another.
git diff newBranch // output: diff --git a/newFileInNewBranch.js b/newFileInNewBranch.js deleted file mode 100644 index e69de29..0000000
Side comment: comparing differences branches/repos, usually visual tools như Meld used. Không phải can't visualize directly terminal, but tools great cho clearer visualization.
- git merge merge (combine) current branch với another. Changes incorporated chỉ current branch, not other one.
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 all previous commits in repo.
git log // output: commit 3a3d62fe7cea7c09403c048e971a5172459d0948 (HEAD -> main, tag: TestTag, origin/main, newBranch) Author: German Cocca Date: Fri Apr 1 18:48:20 2022 -0300 Added new file commit f15cf515dd3ec398210108dce092debf26ff9e12 Author: German Cocca ...
- --help flag show info about given command, same way với 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>...] ...
First script của chúng ta
Ready for truly fun và awesome part: scripting!
Như mentioned, script = series of commands/instructions execute at any given time. Explain how code one, simple example tạo github repo bằng single command. ;)
- Create
.shfile. Put wherever. Tôi gọinewGhRepo.sh. - Open trên text/code editor choice.
- First line:
#! /bin/sh
Đây gọi shebang, function declare shell nào run script.
Remember previously mentioned dùng given shell general interaction và another shell execute script? Shebang là instruction dictate shell nào run script.
Cũng mentioned, dùng "stripped down" shell (sh shells) run scripts vì more efficient (though difference unnoticeable, personal preference). Máy tôi dash as sh shell.
Nếu want script run với bash shebang: #! /bin/bash
- Next line:
repoName=$1
Declare variable repoName, assign value first parameter script receives.
Parameter = set of characters entered after script/command. Như cd, cần directory parameter change directory (ie: cd testFolder).
Identify parameters trong script: dollar sign và order parameter expected.
Nếu expecting more than one parameter:
paramOne=$1 paramTwo=$2 paramThree=$3 ...
- Expecting repo name as parameter. But user forgets enter? Plan for that: code conditional keep asking user enter repo name until parameter received.
Code như sau:
while [ -z "$repoName" ]
do
echo 'Provide a repository name'
read -r -p $'Repository name:' repoName
done
What we're doing:
- While repoName variable not assigned (
while [ -z "$repoName" ]) - Write to console message (
echo 'Provide a repository name') - Read user input assign to repoName (
read -r -p $'Repository name:' repoName)
- Repo name in place, create local Git repo:
echo "# $repoName" >> README.md
git init
git add .
git commit -m "First commit"
Tạo readme file viết single line repo name (echo "# $repoName" >> README.md) rồi init git repo và first commit.
- Upload repo lên github. Tận dụng GitHub API:
curl -u coccagerman https://api.github.com/user/repos -d '{"name": "'"$repoName"'", "private":false}'
curl = command transfer data from/to server dùng supported protocols.
-u flag declare user creating repo (-u coccagerman).
Endpoint GitHub API (https://api.github.com/user/repos)
-d flag pass parameters. Indicate repository name (dùng variable repoName) và set private option false, want public repo.
Lots other config options in API, check docs.
- Sau command, GitHub prompt enter private token authentication.
Nếu chưa có private token, generate tại GitHub Settings > Developer settings > Personal access tokens
- Cool, almost done! Cần remote URL newly created GitHub repo.
Get that dùng curl và GitHub API again:
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 whatever command returns.
-H flag sets header request.
Pass GitHub API endpoint contain username và repo name (https://api.github.com/repos/coccagerman/"$repoName").
Pipe return value của request. Piping = pass return value của process as input value của another process. Dùng | symbol: <process1> | <process2>.
Run jq command, tool process JSON inputs. Get value .clone_url – remote git URL theo data format GitHub API.
- Last step: rename master branch to main, add remote origin just obtained, push code to GitHub! =D
git branch -M main
git remote add origin $GIT_URL
git push -u origin main
Full script trông như:
#! /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 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//"$repoName" | jq -r '.clone_url')
git branch -M main
git remote add origin $GIT_URL
git push -u origin main
- Test script! Execute hai cách.
Option 1: enter shell name pass file parameter: dash ../ger/code/projects/scripts/newGhRepo.sh.
Option 2: make file executable chạy chmod u+x ../ger/code/projects/scripts/newGhRepo.sh.
Then execute file directly: ../ger/code/projects/scripts/newGhRepo.sh.
Done! Script up and running. Everytime need new repo execute script từ whatever directory.
But annoying: need remember exact route script directory. Cool nếu execute script với single command always same independently của current directory?
Enter bash aliases solve problem.
Aliases = cách bash provides making names cho exact commands we want run.
Create new alias, edit bash configuration files in system. Normally located home directory. Aliases defined in different files (mainly .bashrc hoặc .bash_aliases).
Tôi có .bash_aliases file, edit that.
- CLI enter
cdgo home directory. ls -alist all files (hidden) check .bashrc hoặc .bash_aliases.- Open file with text/code editor.
- Write new alias:
alias newghrepo="dash /home/German/Desktop/ger/code/projects/scripts/newGhRepo.sh"
Declare alias name, actual command run script (newghrepo).
Between quotes, define alias does ("dash /home/German/Desktop/ger/code/projects/scripts/newGhRepo.sh")
Pass absolute path script, command works same no matter current directory.
Nếu không know absolute path script, go script directory terminal enter readlink -f newGhRepo.sh. Return full path. ;)
- Done editing, save file, restart terminal, voilà! Run script enter
newghrepo, no matter directory. Much quicker than browser click around create repo! =D
Hope gives little taste optimizations possible với scripting. Requires bit more work first time write, test, setup script. But after that, never perform task manually again. ;)
Round up
Terminal feel intimidating và intricate khi starting out. But certainly worth put time effort learn ins and outs. Efficiency benefits too good to pass up!
Interested learning more terminal và Bash, Zach Gollwitzer awesome crash course series youtube.
Also great tutorials Node và Javascript, recommend follow him. ;)
As always, hope enjoyed article và learned something new. Want, follow me on linkedin hoặc twitter.
Cheers và see you next one! =D
