Linux Shell——函數的使用


文/一介書生,一枚碼農。

scripts are for lazy people.

Linux Shell

函數是存在內存里的一組代碼的命名的元素。函數創建於腳本運行環境之中,並且可以執行。
函數的語法結構為:

function <function-name> {
    <code to execute>
}

創建函數不需要dodone這些關鍵字,只需要大括號來界定函數的作用范圍。
我們可以在命令行中創建一個簡單的函數:

function show_system {
	echo "The uptime is:"
	uptime
	echo
	
	echo "Current dir:"
	pwd
	echo
	
	echo "Date:"
	date
}

在命令行定義上面的函數:

function in command line

然后執行函數:

show_system

最后,我們可以使用type命令查看函數的定義:

type show_system

方法可以有傳遞的參數。在此之前,我們先簡單介紹 sed命令,下面的腳本用來移除文件中的注釋行和空白行。

sed -i.bak '/^\s*#/d;/^$/d' <filename>

詳細介紹一下上面的腳本:

  • sed -i.bak:sed 命令會創建一個以.bak結尾的備份文件,用來備份原始的文件。
  • /^:表示行首。
  • \s*:匹配任何不可見字符,包括空格、制表符、換頁符等。
  • #/:shell 腳本中的注釋標記。 /^\s*#/一起使用用來查找注釋行和帶有不可見字符的注釋行。
  • d:用來刪除匹配的行。
  • ;/^$/d;是表達式的分隔符,后面的表達式跟前面的表達式意思很像,用來刪除空白行, "$"匹配輸入字符串的結束位置。

我們把上面的腳本移到函數中,創建一個名為clean_file的函數:

function clean_file {
  sed -i.bak '/^\s*#/d;/^$/d' "$1"
}

上面的代碼中,我們使用位置參數$1來接收命令行里傳遞的參數,需要注意的是$1 用大括號來括起來。

下面,我們完善clean_file方法,新建一個腳本文件 clean.sh。代碼如下:

#!/bin/bash
# Script will prompt for filename
# And remove commented and blank lines

function is_file {
    if [ ! -f "$1" ] ; then
        echo "$1 does not seem to be a file"
        exit 2
    fi
}

function clean_file {
    is_file "$1"
    BEFORE=$(wc -l "$1")
    echo "The file $1 starts with $BEFORE"
    sed -i.bak '/^\s*#/d;/^$/d' "$1"
    AFTER=$(wc -l "$1")
    echo "The file $1 is now $AFTER"
}

read -p "Enter a file to clean: "
clean_file "$REPLY"
exit 1

其中,wc -l命令用來打印文件行數。
現在,我們新建一個用來測試的文件 test.txt,里面隨便寫些內容:

# This file is just for testing.

Hello.

World.

# new comment.

$

The end.

在 test 文件所在的目錄下,執行 clean.sh腳本:

clean.sh

然后查看 test 文件和 test.bak 文件,發現空白行和注釋行已經刪除。

cat test

這里需要注意的是,shell 腳本是從上至下來執行的,如果在一個函數中調用了另一個函數,那么被調用的函數要定義在調用函數的前面。

當然,除了函數可以傳遞參數外,還可以有返回值。默認情況下,在執行完函數內的最后一行代碼后,方法會返回一個狀態的數字,你可以使用$?變量來查看函數執行的狀態。如果返回值為0,表示方法正常退出,非0表示程序發生錯誤或其他非正常退出。
我們使用return關鍵字來返回一個整數。這里需要注意兩點:

  • 函數一旦執行完就會返回狀態代碼。
  • 狀態代碼的范圍為0到255。

如果不想返回函數的狀態代碼,而是想返回一個字符串或是其他類型,可以使用 echo 變量的方式來返回值。

下面創建腳本文件 translate.sh,用來把文件中的大寫字符轉換為小寫字符:

#!/bin/bash
# Script that translates upper letter to low letter

function to_lower ()
{
    input="$1"
    output=$(tr '[A-Z]' '[a-z]' <<< "$input")
    echo $output
}

while true
do
    read -p "Enter c to continue or q to exit: "
    result=$(to_lower $REPLY)
    echo "After translate: $result"
    
    if [ $result = "q" ] ; then
        break
    fi

done
echo "Finished"

代碼會把輸入的大寫字符變成小寫字符,當輸入"Q"或"q"時程序退出。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM