Skip to content

Input Output

處理用戶輸入

傳遞參數

向腳本傳遞參數

$ ./addem 10 30
bash sehll會將所有命令列參數指派為位置參數(positional parameter)

位置參數的名稱都是標準數字:$0對應腳本名,$1對應第一個命令,…直到$9

factorial=1
for (( number = 1 ; number <= $1; number++ ))
do
    factorial=$[ $factorial * $number ]
done
echo The factorial of $1 is $factorial
exit
如果需要輸入更多命令列參數,參數間必須要用空格分開

將字串作為參數傳遞時,引號並不是數據的一部分,僅用於表明數據的起止 如果腳本需要不只9個參數,需要再加上括號表示

$9 ${10} ${11}
$0會回傳執行時的腳本名,包括相對與絕對路徑,可以用basename過濾掉路徑等不相干參數
name=$(basename $0)


參數測試

  • $#:程式運行時攜帶的命令列參數個數
    if [ $# -eq 1 ]
    then
        fragment="parameter was"
    else
        fragment="parameters were"
    fi
    echo $# $fragment supplied.
    exit
    
  • $*$@:獲取命令列所有參數,$*將所有命令視為一個單詞,而$@則是視為多個字串,可以利用for迴圈遍歷

移動參數

shift

shift參數可以移動命令列參數的位置,默認會將每個位置的變量向左移一個位置,$3變為$2$2變為$1,而$1的值被刪除

count=1
while [ -n "$1" ]
do
    echo "Parameter #$count = $1"
    count=$[ $count + 1 ]
    shift
done
exit


處理選項

處理簡單選項

透過shiftcase提取單個參數

while [ -n "$1" ]
do
    case "$1" in
        -a) echo "Found the -a option" ;;
        -b) echo "Found the -b option" ;;
        -c) echo "Found the -c option" ;;
        *) echo "$1 is not an option";;
    esac
    shift
done
exit

getopt

getopt在處理命令行選項和參數時非常方便,其命令格式如下 getopt optstring parameters * optstring 定義了有效的命令行選項,或選項需要那些參數

例子

$ getopt ab:cd -a -b BValue -cd test1 test2
-a -b Bvalue -c -d -- test1 test2
$
冒號:被放在b後面,代表了b選項需要一個參數

在腳本中使用getopt

使用set命令處理各種變量

set --$(getopt -q ab:cd "$@")

while [ -n "$1" ]
do
    case "$1" in 
        -a) echo "Found -a option";;
        -b) parameter=$2
            echo "Found the -b option with parameter value $param"
            shift;;
        -c) echo "Found -c option";;
        --) shift
            break;;
        *) echo "$1 is not an option";;
    esac
    shift
done

在腳本中使用getopts

與getopt類似,多了些拓展功能,getopts每次只處理一個檢測到的命令列參數,處理完後getopts會退出並返回一個大於0的退出狀態碼

使用方式與getopt類似,有效選項字母會在optstring列出,子母後若要參數值,就會在後面加一個冒號

getopts optstring variable
getopts選項加帶的參數值會被保存到$OPTANG環境變量
echo
while getopts :ab:c opt
do
    case "$opt" in
        a) echo "Found the -a option";;
        b) echo "Found the -b option with parameter value $OPTARG";;
        c) echo "Found the -c option";;
        *) echo "Unknown option: $opt";;
    esac
done
exit

選項標準參考

在Linux系統中,某些選項字母會有隱含的標準含意

選項 描述
-a 顯示所有對象
-d 指定目錄
-e 拓展對象
-f 指定讀入數據的文件
-i 忽略文本大小寫
-l 產生長格式輸出
-n 使用非交互模式
-o 將所有輸出重定向至指定的文件
-q or -s 以靜默模式運行
-r 遞迴處理文件與目錄
-v 生成詳細輸出
-x 排除某個文件
-y 為所有問題回答yes

獲取用戶輸入

read

read命令從標準輸入或另一個文件中接受輸入,獲取輸入後,read會將數據存入變量

  • 範例
echo -n "Enter your name :"
read name
echo "Hello $name, welcome to my script. "
exit

注意:echo -n選項不會在字符串末端輸出換行符,允許用戶緊跟其後輸入數據

  • -p 直接指定提示
read -p "Please enter your age: "age
  • REPLY:包含所有輸入數據的環境變量

  • -t 指定計時器

使用read時,腳本可能一直等著用戶輸入,可以指定一個計時器,若超時read命令會返回非0狀態

if read -t 5 -p "Enter your name : " name
then
    echo "Hello $name, welcome to my script"
else
    echo
    echo "Sorry, no longer waititng for name"
fi
exit
* -n 統計輸入的字符數,當自符數達到預設值時就自動退出 * -s 隱藏顯示輸入

  • 從文件中讀取 從文件中一行一行讀取
    count=1
    cat $HOME/scripts/test.txt | while read line
    do
        echo "Line $count: $line"
        count=$[ $count + 1 ]
    done
    

標準輸入與輸出

STDIN

shell的標準輸入,當使用<時,Linux會從重定向指定的文件替代標準輸入

STDOUT

標準輸出,在terminal上就是顯示terminal

當命令跳出錯誤訊息時,STDOUT並不會處理,shell對於錯誤訊息的處理與普通輸出是分開的

STDERR

shell透過特殊的STDERR處理錯誤訊息,在默認情況下,所有錯誤訊息也都會被送往顯示器

STDERR的文件描述符為2,可以把文件描述符加在重定向之前,只重定向錯誤訊息

ls -al badfile 2> test4
同時重定向錯誤與正常輸出
ls -al test badtest 2> test6 1> test7

腳本重定向輸出

臨時重定向

如果有意在腳本中生成錯誤訊息,可以將單獨一行輸出重定向到STDERR,在文件描述符索引值之前加一個&

echo "This is an error message" >&2

永久重定向

可以使用exec指令,告訴腳本執行期間重定向某個特定文件描述符

exec 1>testout
echo "This is a test of redirecting all output"

exec指令會啟動一個新的shell,並用STDOUT重定向到指定文件

腳本重定向輸入

exec命令允許將STDIN重定向為文件

exec 0< testfile

該命令告訴shell,應該從testfile中讀取輸入

tee

tee能將來自STDIN的數據同時送往兩處,一處是STDOUT,另一處是tee命令列指定的文件名

tee filename

可以配合管道命令來重定向輸出

data | tee testfile

-a將數據追加到指定文件,不使用的話tee將會覆蓋文件內容