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。

沒有留言:

張貼留言