範圍:Functions ~ Prompting [TOC] ## Functions ### 語法 <pre> <font color=#3c78d8>function</font> fname <font color=#3c78d8>( )</font> { action; <font color=#3c78d8>return int;</font> } </pre> - function 名字不能有引號及 $ ### Example ```bash= function f1 () { echo 'This is f1.' } # 省略 () function f2 { echo 'This is f2.' } # 省略 function f3 (){ echo 'This is f3.' } # 省略 () 及 function # f4: command not found # 無法判斷是不是 function f4 { echo 'This is f4.' } ``` ### Return Value ```bash= #!/bin/bash f1(){ echo 'function 1'; } f2(){ echo 'function 2' return 22 } f1 echo \$? is $? f2 echo \$? is $? ``` - 如果沒有用 return 且 function 正常執行,回傳 0 (exit status) ### 傳遞參數 - `vi para.sh` - `./para.sh 1 2 3` ```bash= #!/bin/bash func (){ echo func for i in $@ do echo ${i} done echo end of func } for i in $@ do echo ${i} done func h e l l o ``` - 呼叫 func 時傳入的參數,不等於執行 `para.sh` 傳入的參數 ### Local Variables ```bash= #!/bin/bash f1(){ echo exeu function 1 num=1 #global } f2(){ echo exeu function 2 local num=2 #local } echo set num=0 num=0 f1 echo num=$num echo set num=0 num=0 f2 echo num=$num ``` - 在 function 中,如果要使用 local variables,需在宣告變數時,加上 `local` ### 列出所有 function - 完整列出 function - `declare -f` - `typeset -f` - 只列出 function 名稱 - `declare -F` - `typeset -F` ### 刪除 function - `unset -f fname` ```bash= f_unset(){ echo 'test unset'; } f_unset #test unset unset -f f_unset f_unset #f_unset: command not found ``` --- ## Arithmetic Evaluation - 幾乎與 C 語言一樣 - 算式記得用 `(())`, `$(())` 包住 ```bash= #!/bin/bash num1=1 num2=2 num3=3 ((num3++)) echo "num1 + num2 = $((num1 + num2))" echo "2 ** 5 = $((2 ** 5))" echo num3 = $num3 ``` <!-- - :::spoiler Ans. $((…)) Arithmetic expansion does math 。Arithmetic expansion returns the result of mathematical operations ((…)) Arithmetic evaluation does math 。performs calculations and changes the value of variables. Is done without $ ::: --> ### 宣告變數為整數 - `declare -i var` - 如果沒有宣告成整數,可能會出現非預期的結果 ```bash= #!/bin/bash num1=1 num2=2 declare -i int1=1 declare -i int2=2 num1+=$num2 echo $num1 int1+=int2 echo $int1 ``` > 12 > 3 --- ## Conditional Expressions - True <font color=#3c78d8> ➜ return 0</font> - Flase <font color=#3c78d8> ➜ return 1</font> ### 判斷某個檔案的狀態 :::spoiler 一覽 ||| |-|-| | -a | True if file exists. | -b | True if file exists and is a block special file. | -c | True if file exists and is a character special file. | -d | True if file exists and is a directory. | -e | True if file exists. | -f | True if file exists and is a regular file. | -g | True if file exists and is set-group-id. | -h | True if file exists and is a symbolic link. | -k | True if file exists and its ''sticky'' bit is set. | -p | True if file exists and is a named pipe (FIFO). | -r | True if file exists and is readable. | -s | True if file exists and has a size greater than zero. | -t | True if file descriptor fd is open and refers to a terminal. | -u | True if file exists and its set-user-id bit is set. | -w | True if file exists and is writable. | -x | True if file exists and is executable. | -O | True if file exists and is owned by the effective user id. | -G | True if file exists and is owned by the effective group id. | -L | True if file exists and is a symbolic link. | -S | True if file exists and is a socket. | -N | True if file exists and has been modified since it was last read. ::: #### 檔案是否存在 ```bash= touch file1 #建立空白檔案 [[ -a file1 ]] echo $? [[ -a file2 ]] echo $? ``` #### 檔案大小是否大於零 ```bash= touch file #空白檔 ls -l file # 查看檔案大小 [[ -s file ]] echo $? ``` ### 比較檔案(根據修改時間) #### file1 比 file2 新 <font color=#3c78d8>or file1存在 file2 不存在</font> ```bash= touch file1 touch file2 [[ file1 -nt file2 ]] #newer than echo $? rm file2 [[ file1 -nt file2 ]] echo $? ``` #### file1 比 file2 舊 <font color=#3c78d8>or file1不存在 file2 存在</font> ```bash= touch file1 touch file2 [[ file1 -ot file2 ]] #older than echo $? rm file2 [[ file1 -ot file2 ]] echo $? ``` #### Question - `touch file{1,2}` 哪個檔案比較新? - :::spoiler Ans. nt, ot 都回傳 Flase (zsh 結果不同,猜測可能是精確度的問題) ::: ### 比較 arguments - `arg1 OP arg2` - arg1, arg2 都要是整數 - OP - `-eq` 表示 == - `-ne` 表示 != - `-lt` 表示 < - `-le` 表示 <= - `-gt` 表示 > - `-ge` 表示 >= #### Example ```bash= #!/bin/bash if [[ $# < 2 ]] ;then echo argc should gather than 1 else if [[ $1 -eq $2 ]]; then echo $1 \=\= $2 elif [[ $1 -lt $2 ]]; then echo $1 \< $2 elif [[ $1 -gt $2 ]]; then echo $1 \> $2 fi fi ``` --- ## Exit Status - The exit status of an executed command is the value returned by the **waitpid system call** or **equivalent function**. - between 0 and 255 - The shell may use values above 125 specially. ### Example #### 指令成功執行 <font color=#3c78d8> ➜ return 0</font> ```bash= ls echo $? ``` #### command not found <font color=#3c78d8> ➜ return 127</font> ```bash= a echo $? ``` #### command is found but is not executable <font color=#3c78d8> ➜ return 126</font> ```bash= touch notexecutable.sh ./notexecutable.sh echo $? ``` #### 錯誤使用 Shell 內建指令 <font color=#3c78d8> ➜ return 2</font> ```bash= cd -h #-bash: cd: -h: invalid option #cd: usage: cd [-L|[-P [-e]] [-@]] [dir] echo $? ``` --- ## Job Control ### jobs - `jobs` - 查看目前程序運作狀態  - `jobs -l` - 多出 PID  - `jobs -p` - 只有 PID  - `jobs -r` - 只印 Running  - `jobs -s` - 只印 Stopped  ### 背景執行 - `<command> &` ```bash= sleep 10 & jobs ``` ### 暫停程序 - `Crtl-Z` 可以將程序暫停 ```bash= sleep 10 ^Z jobs ``` ### jobspec - The character % introduces a job specification (jobspec). #### %n - n 為 job number #### %ce ```bash= sleep 10 ^Z read & jobs %r jobs %s ``` #### %+, %- - `%+` - 代表最後一個被暫停的程序 - `%-` - 代表倒數第二個被暫停的程序 ```bash= sleep 10 ^Z sleep 20 ^Z sleep 30 ^Z jobs ```  ### 繼續執行被暫停的程序 #### 在背景繼續執行 ```bash= # bg <job number> sleep 10 ^Z jobs bg 1 ``` ```bash= # %[] & sleep 10 ^Z jobs %1 & ``` #### 移至前景繼續執行 ```bash= # fg <job number> sleep 10 ^Z jobs fg 1 ``` ### kill - `kill %[]` - 刪除背景程序 ### pipeline  --- ## Prompting - BASH 可以使用跳脫字元自訂 PS1, PS2 ### `$` or `#` ```bash= PS1='\$ ' ``` - root 顯示 `#` - 其他 user 顯示 `$` ### Bell ```bash= PS1='\a\$ ' # or PS1='\007\$ ' ``` ### Time #### a. Date ```bash= PS1='\d \$ ' ``` #### b. Current Time ```bash= # 24-hour HH:MM:SS format PS1='\t \$ ' # 12-hour HH:MM:SS format PS1='\T \$ ' # 12-hour am/pm format PS1='\@ \$ ' # 24-hour HH:MM format PS1='\A \$ ' ``` #### c. 自訂格式 ```bash= PS1='\D{} \$ ' PS1='\D{%M:%H} \$ ' PS1='\D{%h %d %a} \$ ' ``` - {} 內的格式可以查看 [strftime(3)](https://linux.die.net/man/3/strftime) ### Color ```bash= PS1='\e[32mHello!\e[0m > ' PS1='\e[1;32mWorld!\e[0m > ' PS1='\e[4;34;46mBASH!!\e[0m > ' ``` - 指定顏色 - \e\[<font color=#3c78d8>文字顏色</font>m - \e\[<font color=#3c78d8>文字樣式</font>;<font color=#3c78d8>文字顏色</font>;<font color=#3c78d8>背景顏色</font>m (沒有順序性,樣式可以多選) - :::spoiler 文字樣式 0 一般樣式 1 高亮度 4 底線 5 灰底 7 反白 ::: - :::spoiler 文字顏色 30 黑色 31 紅色 32 綠色 33 黃色 34 藍色 35 紫色 36 青綠色 37 白色 ::: - :::spoiler 背景顏色 40 黑色 41 紅色 42 綠色 43 黃色 44 藍色 45 紫色 46 青綠色 47 白色 ::: - 還原原始顏色 - \e\[0m ### History Number & Command number ```bash= PS1='\! \$ ' PS1='\# \$ ' # 比較差別,可以重新連線再檢查一次 PS1='\! \# \$ ' ``` - Command number 只有這次 Session 的 command seq - History Number 包含過去的 command 紀錄 ### Exercise  - Hint - (高亮度+底線+紫色) history - (反白) 完整星期 - (無樣式) $ or # - (藍色) - :::spoiler Ans. `PS1='\e[0m\e[1;4;35m\!\e[0m \e[7m\D{%A}\e[0m \$ \e[36m'` :::
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up