引數、回傳值與作用域

Bash 指令稿入門

Alex Scriven

Data Scientist

將引數傳入 Bash 函式

將引數傳入函式的方式,和傳入腳本很像,使用 $1 標記。

你也可以使用先前介紹過的特殊 ARGV 屬性:

  • 每個引數可用 $1$2 取得。
  • $@$* 會給出 ARGV 中的所有引數。
  • $# 會給出引數的數量。
Bash 指令稿入門

傳遞引數範例

我們把一些檔名當作引數傳入函式示範。會用迴圈逐一印出。

function print_filename {
    echo "The first file was $1"

for file in $@ do echo "This file has name $file" done }
print_filename "LOTR.txt" "mod.txt" "A.py"

 

 

 

The first file was LOTR.txt
This file has name LOTR.txt
This file has name mod.txt
This file has name A.py
Bash 指令稿入門

程式中的作用域

 

程式中的「作用域」指的是變數的可存取範圍。

  • 「全域」表示在程式任何地方都能存取,包含 FOR 迴圈、IF 判斷、函式等。
  • 「區域」表示只能在程式的某一部分存取。

為什麼重要?如果你嘗試存取只有區域作用域的東西,程式可能會因錯誤而失敗!

Bash 指令稿入門

Bash 函式的作用域

與多數程式語言(如 Python、R)不同,Bash 中的變數預設都是全域的。

function print_filename {
    first_filename=$1
}

print_filename "LOTR.txt" "model.txt" echo $first_filename
LOTR.txt

注意,全域作用域可能有風險,較容易發生非預期行為。

Bash 指令稿入門

在 Bash 函式中限制作用域

你可以用 local 關鍵字限制變數的作用域。

function print_filename {
    local first_filename=$1
}

print_filename "LOTR.txt" "model.txt" echo $first_filename


 

問:為什麼沒有錯誤,只是空白一行?

答:first_filename 被指派為「全域」的第一個 ARGV 元素($1)。

我是在沒有引數的情況下執行腳本(bash script.sh),因此會預設成空字串。要小心!

Bash 指令稿入門

回傳值

我們知道怎麼把值傳進來,那要怎麼把它們帶出去?

Bash 的 return 只用來表示函式是否成功(0)或失敗(其他值 1–255)。結果會存在全域變數 $? 中。

可行作法:

  1. 指派到全域變數
  2. 在函式最後一行用 echo 輸出,並用巢中殼(shell-within-a-shell)擷取
Bash 指令稿入門

回傳錯誤範例

來看一個回傳錯誤:

function function_2 {
    echlo # An error of 'echo'
}

function_2 # Call the function echo $? # Print the return value
script.sh: line 2: echlo: command not found
127

發生了什麼事?

  1. 呼叫函式時發生錯誤
    • 腳本嘗試尋找『echlo』這個程式,但不存在。
  2. $? 的回傳值為 127(錯誤)。
Bash 指令稿入門

正確回傳

我們用 echo 搭配巢中殼擷取,正確回傳一個可在腳本其他地方使用的值:

function convert_temp {
    echo $(echo "scale=2; ($1 - 32) * 5 / 9" | bc)
}

converted=$(convert_temp 30) echo "30F in Celsius is $converted C"
30F in Celsius is -1.11 C
  • 注意我們不再建立中介變數了。
Bash 指令稿入門

一起來練習吧!

Bash 指令稿入門

Preparing Video For Download...