顯示具有 shell 標籤的文章。 顯示所有文章
顯示具有 shell 標籤的文章。 顯示所有文章

2018年5月8日 星期二

Bash Shell | 如何在 script 中引入 include 其它 script

當 script 越寫越複雜後,會想要把共用 function 獨立寫在一個 script,再利用像 C 語言的 #include 方式來引入,此時可以使用 builtin command source 來達成,source 也可以用同義符號 ( . ) 替代。

source filename

or

. filename


底下是一個會將參數累加起來的 function

範例:

共用 script (func.sh)

#!/bin/sh

sum()
{
        total=0
        count=0

        echo The PID of sum\(\) = $$

        if [ "$#" -lt "2" ]; then
                echo "The number of arguments should larger than 1."
                return 255;
        fi

        for i in $@
        do
                ((total += i))
                ((count += 1))

                echo -n $i

                if [ "$count" -lt "$#" ]; then
                        echo -n " + "
                fi
        done

        echo " = $total"

        return $total

}

測試 script (test.sh)

#!/bin/sh

source ./func.sh

echo The PID of $0 = $$
echo ""

sum 1 2
echo The return of sum\(\) = $?
echo ""

sum 3 4 5
echo The return of sum\(\) = $?
echo ""

sum 6
echo The return of sum\(\) = $?

結果:


The PID of ./test.sh = 2075

The PID of sum() = 2075
1 + 2 = 3
The return of sum() = 3

The PID of sum() = 2075
3 + 4 + 5 = 12
The return of sum() = 12

The PID of sum() = 2075
The number of arguments should larger than 1.
The return of sum() = 255

說明:

test.sh 在開頭使用 source 引入 func.sh 後呼叫了三次 sum(),從 PID 可以看出,sum() 是由執行 test.sh 的 process 所執行。

2017年12月11日 星期一

Bash Shell | 如何使用管線 Pipeline


管線 Pipeline 可以將一個指令的輸出給另外一個指令當做輸入,格式如下

command1 [ | or |&  command2 ] ...

管線有兩種代表符號
1. ( | )
   將一個指令的輸出(stdout)給另一個指令當作輸入,底下是取得網路介面 IP 的範例

範例:

#!/bin/sh

echo "1. The output of ifconfig eth0:"
echo ""
ifconfig eth0
echo "---------------------------------------------------------"
echo "2. The output of ifconfig eth0 | grep \"inet addr\""
echo ""
ifconfig eth0 | grep "inet addr"
echo "---------------------------------------------------------"
echo "3. The output of ifconfig eth0 | grep \"inet addr\" | awk '{print \$2}'"
echo ""
ifconfig eth0 | grep "inet addr" | awk '{print $2}'
echo "---------------------------------------------------------"
echo "4. The output of ifconfig eth0 | grep \"inet addr\" | awk '{print \$2}' | awk -F':' '{print \$2}'"
echo ""
ifconfig eth0 | grep "inet addr" | awk '{print $2}' | awk -F':' '{print $2}'


結果:

1. The output of ifconfig eth0:

eth0      Link encap:Ethernet  HWaddr 08:00:27:08:DA:E6  
          inet addr:192.168.1.115  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe08:dae6/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:33355 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5186 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:6077695 (5.7 MiB)  TX bytes:415741 (405.9 KiB)

---------------------------------------------------------
2. The output of ifconfig eth0 | grep "inet addr"

          inet addr:192.168.1.115  Bcast:192.168.1.255  Mask:255.255.255.0
---------------------------------------------------------
3. The output of ifconfig eth0 | grep "inet addr" | awk '{print $2}'

addr:192.168.1.115
---------------------------------------------------------
4. The output of ifconfig eth0 | grep "inet addr" | awk '{print $2}' | awk -F':' '{print $2}'

192.168.1.115

2. ( |& )
   將一個指令的輸出(stdout 與 stderr)給另一個指令當作輸入

範例:

#/bin/sh

unset var1
echo "1. The output of declare -p var1"
echo ""
declare -p var1
echo "---------------------------------------------------------"
echo "2. use |"
if declare -p var1 | grep "not found"; then
        echo "keyword is found"
else
        echo "keyword is not found"
fi
echo "---------------------------------------------------------"
echo "3. use |&"
if declare -p var1 |& grep "not found"; then
        echo "keyword is found"
else
        echo "keyword is not found"
fi


結果:

1. The output of declare -p var1

./pipelines.sh: line 24: declare: var1: not found
---------------------------------------------------------
2. use |
./pipelines.sh: line 27: declare: var1: not found
keyword is not found
---------------------------------------------------------
3. use |&
./pipelines.sh: line 34: declare: var1: not found
keyword is found

說明:

利用 declare 指令找不到參數名時會往 stderr 送出錯誤訊息的特性,範例中使用兩種不同管線 Pipelines 得到不同的結果。當使用 ( | ) 時,grep 因為沒有收到 declare 往 stderr 送出的錯誤訊息,因此結果是 keyword is not found,而使用 ( |& )時,因為 declare 的 stderr 也會一併給 grep,所以結果是 keyword is found。