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後的空格