Introduce to Linux Command Line
Wen Liao
Outlines
Backgrounds Command Lines Shell Scripts Regular Expression
非常淺略介紹 Command line 和 Shell script 詳細細節請要回去看書
Test/Study Environments
Ubuntu 12.04.3 LTS bash, version 4.2.25(1)
參考資料
2013 8 月份 SA@Tainan 從 shell 開始 8/10教材 https://sites.google.com/a/study-area.org/sa-
activity/home/2013-08-tn 鳥哥的 Linux 私房菜
http://linux.vbird.org/ man bash
Shell ( 理論上的定義)
OS Kernel
Shell
(CLI) Command Line Interface
(GUI) Graphics User Interface
Shell ( 實際上的情況一)
OS Kernel
Shell (GUI)
CLI
Shell ( 實際上的情況二)
OS Kernel
Shell (CLI)
GUICLI
本次 Shell 指的
Kernel 和應用程式的介面 CLI
理解並且讓 OS 執行從檔案輸入的 Command Unix 所有東西都是檔案,包含鍵盤、滑鼠、螢幕
Outlines
Backgrounds Command Lines Shell Scripts Regular Expression
wen:/tmp/$ echo -n test1 test2
test1 test2wen:/tmp/$
第一提示符號(PS1)
Command Option 或Parameter
Argument: 要處理的對象
Command line 的組成
wen:/tmp/$ echo "
> test1
> test2
> "
test1
test2
第一提示符號(PS1) Command
Argument: 要處理的對象
Argument: 要處理的對象
Option 或Parameter 可以是空的
第二提示符號(PS2)
Command line 的組成
-- :後面的都是 Argument
$ touch -- -al
$ ls -al -- -al
-rw-rw-r-- 1 test test 0 Sep 12 15:31 -al
$ rm -al
rm: invalid option -- 'a'
Try `rm ./-al' to remove the file `-al'.
Try `rm --help' for more information.
$ rm -- -al
IFS: Internal Field Separator
切割 token 的辨別字元,預設為空白,跳行和<tab> ls -al /tmp 可以切割成 3 個 token
ls -al /tmp
$$ command
command
fork() + exec() exit() 或是 kill
Foreground mode
Command 可以取得鍵盤輸入的資料
Shell 須要等 command結束才能執行下一個
command
$$ command &
command
fork() + exec()
Background mode
鍵盤輸入的資料傳給 shell而不是 command
Shell 不須等 command結束就能執行下一個
command
撒尿牛丸 (1)
Shell
鍵盤傳送 Process 對象
Command Shell
執行 commandCTRL + Z 暫停
Command
撒尿牛丸 (2)
Shell
鍵盤傳送 Process 對象
Command Shell
執行 command &CTRL + Z 暫停
Command
Shell
執行 fg 把 command轉回 foreground
Command 遺言
正常結束 0
有錯誤 非 0
用 $? 取得
$ ls testtest
$ echo $?0
$ ls --badls: unrecognized option '--bad'Try `ls --help' for more information.
$ echo $?2
Command line 特殊字元
Meta-character > < ; ...
控制字元 | || ...
Quote
Quote 把書上或是別人說的話一字不漏地原封抄下 也就是引用
Command line 中指的就是要 Shell 把 Meta-character 和控制字元當作一般文字處理
Quote
Hard Quoting: 成對的 ' ,第一個 ' 右邊所有的特殊字元都會視為一般字元直到第二個 ' 出現
Soft Quoting: 成對的 " ,第一個 " 右邊大部份的特殊字元都會視為一般字元直到第二個 " 出現 例外仍然有特殊意義的字元 $ ` \ ! ( 有 enable history 功能 )
跳脫字元 \
一行執行多個 commands (1)
List 條件式
&& ||
無條件式 ;
一行執行多個 commands (2)
(List) 會 fork sub-shell 去跑 list 內的命令
{ List; } 第一個 { 後面要有一個空白,不會 fork
Pipe: 把前面的輸出轉給後面處理
屠宰 烹煮
$ 屠宰 豬隻 | 烹煮 梅干扣肉我是梅干扣肉
Image: http://www.wikipedia.org/
範例
find | grep lib.*\\.a$ 找出目錄下面所有 lib 開頭 .a 結尾的檔案
find grep
列出出目錄下面所有檔案 從前面輸出過濾出要找的字串
File Descriptor
簡稱 fd Linux command 開檔案都會有對應的數字代號
/proc/[process id]/fd 關鍵字 :Process, process ID, file descriptor
每個 command 初始都會有 3 個開啟的檔案 0: stdin 1: stdout 2: stderr
Redirect
輸出 Redirect Fd> 檔案
預設 1> ls > file ls -no_such_option 2> error_file
複製輸出 fd Fd1>&Fd2
make 2>&1 | tee build.log
Redirect
輸入 Redirect Fd< 檔案
預設 0< cat < /tmp/test
執行 command 方法一
$$ command
command
fork() + exec() exit() 或是 kill
Command 不會影響到 shell的內建變數
執行 command 方法二
$$ exec command
Exec 取代 shell 的記憶體空間。Command 結束後終端機就會結束
執行 command 方法三
$$ source command
Command 只限 shell script
Command 內的變數會影響Shell 的變數
Shortcuts
CTRL + R: 搜尋打過的指令 CTRL + A: 切到 command 第一個字元 CTRL + E: 切到 command 最後一個字元 CTRL + Z: 暫停目前 command CTRL + S: 停止螢幕捲動 CTRL + Q: 恢復螢幕捲動
X 下面的關於 Copy/Paste
滑鼠左鍵 連點兩下:選一個字 連點三下:選一行
滑鼠中鍵 貼上滑鼠點選的字
Gnome-terminal shortcuts
CTRL+SHIFT+C: COPY CTRL+SHIFT+V: PASTE CTRL+SHIFT+T: New TAB SHIFT+INS: PASTE 滑鼠選的字 CTRL+SHIFT+F: 搜尋
Outlines
Backgrounds Command Lines Shell Scripts Regular Expression
Shell script 是?
一連串的 commands 支援迴圈和條件判斷的語法
Why Shell Script?
取代重覆無聊的操作 自動化 想像一下
臨時需要5000個圖檔? 需要連續重覆執行測試程式一個星期 ...
簡單型式
#!/bin/sh
Command1
Command2
….
變數
VAR=1 VAR= 字串 使用 $ 取值
$VAR
環境變數
所有的 process在 fork 都會繼承的變數 在單一 shell 下更改環境變數後,該 shell之後
fork 的 process環境變數都會繼承改變的環境變數
範例 $PATH $HOME
可以用 env檢查環境變數
條件判斷
If [ 條件式 ] ; then
Command1
Command2
…
fi
可以判斷條件舉例 數字 字串 檔案
請 man [
[ 是一個執行檔
迴圈
while [ 條件 ] ; do
Command1
Command2
…
done
For 迴圈
for 變數 in list
do
Command1
Command2
…
done
List使用 IFS隔開
數學運算
$(( 數學運算 ))
VAR=100
VAR=$(($VAR+1))
取得 command 輸出
$(command1) `command1`
echo $(ls)
範例一:變數
PATH=$PATH:/home/user/bin VAR=$((1+1)) VAR=$(echo test) VAR=$?
範例二:列印 0~9 的迴圈
#!/bin/sh
i=0
while [ $i -lt 10 ] ;
do
echo $i
i=$(($i+1))
done
範例三:印出目前目錄詳細資料
#!/bin/sh
files=$(ls)
for i in $files
do
ls $i -al
done
Outlines
Backgrounds Command Lines Shell Scripts Regular Expression
Regular expression
一個描述字串 pattern 的語法,如 Lib 開頭 .a 結尾的字串 變數 my_var被 assgin 的字串
注意 = 前後可能有 0 到多個空白 ...
80/20 法則 : 個人常用的語法
^ 一行的開始
$ 一行的結束
* 零個或多個任何字元
. 單個任何字元
範例 grep
找出檔案裏面變數 my_var被 assign 的行數 grep * -r my_var.*=
找出目錄下面所有 lib 開頭 .a 結尾的檔案 find | grep ^./lib.*\\.a$
範例 :vim
把每檔案一行最前面加上 PRE 的字串 %s/^/PRE_/g
把每檔案一行最後面加上分號 %s/$/;/g
實習時間
假設使用 gnome-terminal / X環境
請打下面的指令ls (enter)
ls -al (enter)
CTRL + R (再打 l)
第二次 CTRL + R
請打下面的指令
ls /tmp /usr
Ctrl + a
Ctrl + e
Ctrl + w
Ctrl + w
Ctrl + w
請打下面的指令
echo hello world (enter)
滑鼠游標到顯示的 hello world那行中的 world
Double click ( 左鍵 )
Click ( 左鍵 )
echo 後 click 中鍵echo 後按 shift + ins
請打下面的指令
echo hello world (enter)
滑鼠游標到顯示的 hello world那行中的 world
Double click ( 左鍵 )
Ctrl + shift + c
echo 後 Ctrl + shift + v 再按 enter
ctrl + l
ctrl + shift + t
變數 , IFS 以及 quote
VAR1=my test
echo $VAR1
VAR1="my test"
echo $VAR1
for i in $VAR1; do echo $i ; done
變數以及 quote
VAR1="my test"
echo $VAR1
echo “$VAR1”
echo '$VAR1'
echo \$VAR1
變數計算
VAR=1(enter)
while [ $VAR -lt 100 ] ; do echo $((VAR++)) ; done (enter)
Job control
vi (enter)
Ctrl + z
fg (enter)
Quit vi
Job control
while [ true ] ; do echo test ; sleep 5 ; done Enter Ctrl + c
Job control
while [ true ] ; do echo test ; sleep 5 ; done & Enter
vi (enter)
Ctrl + z
jobs (enter)
fg 1 (enter)
Ctrl + c
fg 2 (enter)
Quit vi
Return value and conditional
ls (enter)
if [ $? = 0 ] ; then echo ok; else echo bad; fi (enter)
ls --bad (enter)
if [ $? = 0 ] ; then echo ok; else echo bad; fi (enter)
Return value and conditional
ls && echo ok || echo bad
ls --bad && echo ok || echo bad
Redirect
ls / (enter)
ls / > /dev/null (enter)
ls / > /tmp/dct (enter)
cat /tmp/dct (enter)
Redirect and fd
rm /tmp/dct (enter)
ls / --bad > /tmp/dct (enter)
cat /tmp/dct (enter)
ls / --bad 2> /tmp/dct (enter)
cat /tmp/dct (enter)
pipeline
ls /lib | grep lib.*\\.so$ (enter)
rm -f /tmp/dct (enter)
ls / | tee /tmp/dct (enter)
cat /tmp/dct (enter)
Command Substitution and IFS
echo $(ls /)
echo `ls /`
for i in $(ls /) ; do ls -ald /$i; done