1. 程式人生 > >shell指令碼的那點小事兒--shell指令碼管道和重定向(四)

shell指令碼的那點小事兒--shell指令碼管道和重定向(四)

 

內容一:shell指令碼管道

分析場景:一個命令的輸出作為另外一個命令的輸入

語法結構: command1 | command2

內容二:輸入/輸出重定向

1.expr 關鍵字的應用

e.g:

#!/bin/bash

function operationAdd1() {

    number1=${1}
    number2=${2}
    result=`expr $number1 + $number2`
    return $result

}

function operationAdd2() {

    result=$(expr ${1} + ${2})
    return $result

}

function operationAdd3() {

    return $[${1} + ${2}]

}

operationAdd1 $1 $2
echo "result1: ${?}"

operationAdd2 $1 $2
echo "result2: ${?}"

operationAdd3 $1 $2
echo "result3: ${?}"

#shell中的運算可以一類expr和[]來完成

expr操作表格

操作符 描述
ARG1 | ARG2 如果ARG1既不是null也不是零值,那麼返回ARG1,否則返回ARG2
ARG1 & ARG2 若兩邊的值都不為0 或為空,則返回ARG1,否則返回 0
ARG1 < ARG2 ARG1 小於ARG2
ARG1 <= ARG2 ARG1 小於或等於ARG2
ARG1 = ARG2 ARG1 等於ARG2
ARG1 != ARG2 ARG1 不等於ARG2
ARG1 >= ARG2 ARG1 大於或等於ARG2
ARG1 > ARG2 ARG1 大於ARG2
ARG1 + ARG2 計算 ARG1 與ARG2 相加之和
ARG1 - ARG2 計算 ARG1 與ARG2 相減之差
ARG1 * ARG2  計算 ARG1 與ARG2 相乘之積
ARG1 / ARG2 計算 ARG1 與ARG2 相除之商
ARG1 % ARG2 計算 ARG1 與ARG2 相除之餘數

2.浮點數

2.1 bash 基本用法

bash計算器,實際上bash是一種程式語言

bash提供了執行浮點數的命令,允許在命令中輸入浮點數,解釋並且計算表示式,返回結果。

可以識別的資料型別

1.整數,浮點數

2.變數,簡單的變數陣列

3.註釋,表示式

bc 命令,shell指令碼通過bc訪問bash

開啟計算器 bc 退出計算器quit

 

shell指令碼中運用bash計算器

語法結構:

val=$(echo "options;expression" | bc)

案例一:

function func1 () {

    #val=$(echo "options;expression" | bc)
    #option:選項
    #expression 表示式
    val=$(echo "scale=30;${1} * ${2}" | bc)
    val2=$(echo "$val * ${2}" | bc)
    echo $val2
    return $val

}
func1 $1 $2
echo "val=${?}"

案例二: bc命令+輸出重定向

#!/bin/bash
function func2 () {
    
    val1=$1
    val2=$2
    val3=$3
    val4=$4
    val=$(bc<<sign
            scale=1
            a=($val1 * $val2)
            b=($val3 * $val4)
            a * b
          sign
         )
    echo "val=$val"
}

func2 $1 $2 $3 $4

#解析:
#val=$(bc<<標誌符號
#        options
#        statements
#        expression
#        標誌符號
#        )
# 標誌符可以為任意字元,只需保持前後兩個標誌符號一致即可,一般使用EOF作為標誌符,兩個標誌符號直接的內容視為一個整體

4.重定向的輸出

4.1如何理解輸入,輸出和錯誤

在shell 指令碼中將:輸入,輸出,錯誤分為了三種描述符(3種狀態),分別對應的值為0,1,2

4.1.1第一種狀態:STDIN->標準輸入->0->鍵盤輸入,檔案讀取

cat指令,接收鍵盤輸入並且列印輸出

a)cat STDIN標準輸入

b)cat 非STDIN輸入

 

第二種狀態:STDOUT->標準輸出->1->對應終端顯示

a)重定向輸出到檔案

ls -l 顯示檔案的資訊

b)將錯誤輸出到檔案中

檔案a.sh程式碼如下

#!/bin/bash
if[ $0 ] 
    echo "false"
else 
    echo "success"
fi
#這一段指令碼存在語法的錯誤,if與[]之間應有空格,if-else語句缺少了then關鍵字

終端輸入:ls -al a.sh >> error.text

"-al":檔案列表

shell不會將錯誤資訊重定向到檔案裡面,雖然建立了error.text但不會將錯誤寫入error.text,error.text內容為空

如果需要捕獲異常需要通過STDERR去捕獲

STDOUT和STDERR結合檢視

STDERR的值為2

應在終端輸入:ls -al a.sh 2> error.text

4.2.1重定向錯誤:

ls al fileC.sh 2> error.sh

4.2.2STDOUT和STDERR結合使用,向不同檔案輸出錯誤和檢視的資訊

重定向錯誤和重定向資料2>和1>

第一步:執行命令 

終端輸入:ls -al fileA.sh fileB.sh fileC.sh 2> error.sh

第二步:檢視結果

終端輸入:ls -l fileA.sh fileB.sh

終端合併步驟一二得出:ls -al fileA.sh fileB.sh fileC.sh 2> error.sh 1> fileContent.sh

4.2.3將錯誤和資訊重定向到同一個檔案

終端輸入:ls -al fileA.sh fileB.sh fileC.sh &> error.sh

4.3重定向輸出

4.3.1 臨時重定向"&"

案例一:

#!/bin/bash
echo "hello world" > &2
echo "你好世界"

#將echo "hello world" 定義為一個錯誤資訊的列印
#終端輸入:ls -al fileA.sh fileB.sh fileC.sh &> error.sh

案例二:

#!/bin/bash
#將下面的列印視為錯誤列印
echo "hello world" > &2
echo "你好世界"

執行:

./fileB.sh > error.sh # > 將正常標準輸出列印到error.sh檔案
./fileB.sh &> error.sh # &> 將所有輸出列印到error.sh檔案
./fileB.sh 2> error.sh # 2> 將輸出列印到error.sh檔案

4.3.2永久重定向

exec命令

exec 1> fileContent.sh 或者 exec 1>> fileContent.sh
exec 2> fileContent.sh 或者 exec 2>> fileContent.sh
exec &> fileContent.sh

e.g

#!/bin/bash
exec 1> fileContent.sh #exec 1> 將正常標準輸出列印到 fileContent.sh
exec 2> fileContent.sh #exec 2> 將錯誤輸出列印到 fileContent.sh

echo "hello shell"
echo "I am error" >&2 

5. 重定向的輸入

5.1.1從檔案輸入內容

#!/bin/bash

exec fileContent.sh

count=0
while read line
do
    echo "line${count}: ${line}"
    count=$[ $count + 1 ]
done

#從fileContent.sh輸入內容, read接收輸入

6.建立自定義的重定向

系統提供了0,1,2的定向

6.1建立自己(自定義)輸入檔案描述

案例一:建立新的檔案,或者替換內容

#!/bin/bash

#exec 建立重定向型別
exec 4> fileContent.sh
#標記輸出的內容
echo "hello world" > &4

7.恢復檔案描述符

7.1

#!/bin/bash

#最開始是40,重定向到1
exec 40 >> &1
exec 1 >> fileContent.sh
exec 40 >> error.sh
echo "hello shell"

#將還原為40
exce 1 >> &40
echo "你好, shell"

#重定向輸出還原

8.輸入重定向恢復

#!/bin/bash

exec 6<&0
exec 0< fileContent.sh

count=0
while read line
do
    echo "line${count}: ${line}"
    count=$[ $line + 1]
done

exec 0<&6
read -p "你是不是一個男人: " isMan
case $isMan in
    yes) echo "是男人";;
    no) echo "是女人";;
    *) echo "是人妖";;
esac

9.讀寫描述符

檔案的內容

fileContent.sh內容程式碼

hello shell

你好 shell

fileA.sh指令碼程式碼

#!/bin/bash

exec 4<>fileContent.sh
while read line <&4
do
    echo "${line}"
done
echo "我已經讀完了" >&4

這裡採用自定義,這種情況下需要按讀取的指標指向內容後面追加內容或替換內容,

這裡迴圈讀取了多有內容,所以在指標運動到了文字的最後,所以效果為在原文字後追加新的輸入

注意:以上的縮排是為了方便檢視層級關係,如果在執行程式碼中報錯(not found command),請去除縮排,注意if後的空格