1. 程式人生 > >Linux Shell筆記之輸入與輸出

Linux Shell筆記之輸入與輸出

一、獲取輸入
1.命令列引數
#!/bin/bash
name=`basename $0`                       $0引數獲取shell在命令列啟動的程式的名字,basename命令去掉路徑
echo "current command is $name"
if [ -n "$1" ] && [ -n "$2" ]            $1、$2分別代表第一個引數與第二個引數,第9個變數後,需加花括號
then                                     如${10},-n判斷引數是否非空
   sum=$[ $1 + $2 ]
   echo "$1+$2=$sum"
else
   echo "please input two number"
fi

[
[email protected]
hunterno4]# ./add 3 4    引數若含空格需加引號
current command is add
3+4=7

2.特殊引數變數
1)$#
#!/bin/bash
param=$#
echo "total parameter is $#"            指令碼執行時命令列引數的個數
echo "the last parameter is ${!#}"      不能在花括號內使用美元符,需要換成!號

2)$*與[email protected]
#!/bin/bash
count=1
for param in "$*"
do 
   echo "\$* parameter-- $param"
done

for param in "
[email protected]
"
do 
   echo "\[email protected] parameter-- $param"
done

# ./param one two three
$* parameter-- one two three             $*將命令列中的所有引數當單個單詞儲存
[email protected] parameter-- one                       [email protected]將命令列中的所有引數當同一字串中的多個獨立的單詞
[email protected] parameter-- two
[email protected]
parameter-- three

3.移動變數
#!/bin/bash
count=1
while [ -n "$1" ]
do 
   echo "current \$1 is $1"
   count=$[ $count + 1 ]
   shift                                 使用shift命令,預設情況每個引數變數減一,shift n 則移n位
done                                     引數移除後,無法恢復,$0不會改變

# ./shift one two three
current $1 is one
current $1 is two
current $1 is three

4.處理選項
1)getopt                                       格式化命令列選項與引數:getopt optstring options parameters
# getopt -q ab:cd -a -b test1 -cd test2 test3   ab:cd定義了命令列有效的選項字母,在需要引數值的字母后加:號
 -a -b test1 -c -d -- test2 test3               -q忽略錯誤資訊,getopt命令不能處理含空格引數

#!/bin/bash
set -- `getopt -q ab:c "[email protected]"`
while [ -n "$1" ]
do
   case "$1" in
   -a) echo "found -a";;
   -b) param="$2"
       echo "found -b,with parameter $param"
       shift;;
   -c) echo "found -c";;
   --) shift                                     引數和選項預設用--特殊字元分隔,碰到--則結束選項處理,進入引數處理流程
       break;;
    *)  echo "$1 is not a option"
   esac
   shift
done

count=1
for param in "[email protected]"
do
   echo "parameter #@count: $param"
   count=$[ $count + 1 ]
done

2)getopts                                      標準格式:getopts optstring variable
#!/bin/bash
while getopts :ab:cd opt                        optstring前加:號忽略錯誤訊息,getopts將當前引數儲存在variable中
do
   case "$opt" in
   a) echo "found -a";;                         case定義中不需再用單破折線
   b) echo "found -b,with parameter $OPTARG";;  OPTARG環境變數儲存選項需要的引數值
   c) echo "found -c";;
   d) echo "found -d";;
   *) echo "unknown option: $opt";;
   esac
done
shift $[ $OPTIND -1 ]                           OPTIND環境變數儲存了引數列表中getopts正在處理的引數位置

count=1
for param in "[email protected]"
do
   echo "parameter $count: $param"
   count=$[ $count + 1 ]
done

# ./getopts -a -b "one two" -s
found -a
found -b,with parameter one two                 支援空格引數
unknown option: ?                               未定義的選項統一以?號輸出

5.獲取使用者輸入
1.read
1)常規輸入
#!/bin/bash
echo -n "enter your name:"                      -n,移除字串末尾的換行符,使指令碼使用者緊隨其後輸入資料
read name                                       獲得輸入,指定變數名name,不指定則預設為變數REPLY
echo "welcome $name"

#!/bin/bash
read -p "enter your name:" name                 -p可直接在read命令列指定提示符
echo "welcome $name"

2)指定超時時間
#!/bin/bash
if read -t 3 -p "enter your name:"              -t指定超時時間
then
   echo "welcome $REPLY"
else
   echo
   echo "sorry time out"
fi

3)指定接收的字元數
#!/bin/bash
read -n1 -p "continue [Y/N]:" answer             -n1,read命令在接受單個字元後退出
case $answer in
   Y|y) echo
        echo "ok continue";;
   N|n) echo
        echo "ok goodbye"
        exit;;
esac
echo "end"

4)隱藏方式讀取
#!/bin/bash
read -s -p "enter your passwd:" passwd          -s,阻止傳給read命令的資料顯示在顯示器上(背景色一樣)
echo 
echo "passwd right? $passwd"

二、重定向輸入與輸出
1.檔案描述符
Linux中將每個物件當作檔案處理,包括輸入與輸出,用檔案描述符來標識每個物件,共9個檔案描述符
0      STDIN      標準輸入
1      STDOUT     標準輸出
2      STDERR     標準錯誤

2.重定向輸入與輸出
# cat < testfile                         重定向cat的輸入
# ls -l > test2file                      重定向ls -l命令的輸出到test2file檔案,>>則這追加到檔案末尾
# ls -al badfile 2> test4                重定向錯誤
# ls -al read badfile 2> test5 1> test6  同時重定向標準錯誤與標準輸出                       
# ls -al read badfile &> test7           同時重定向標準錯誤與標準輸出,錯誤訊息會顯示在最前

3.在指令碼中重定向輸出
1)臨時重定向輸出
#!/bin/bash
echo "this is error line" >&2           臨時重定向本行
echo "this is normal line"

# ./redirect 2> error                   指令碼中的錯誤行重定向到檔案
this is normal line
# cat error 
this is error line

2)永久性重定向輸出
#!/bin/bash
exec 1> stdout.txt                       exec命令告訴shell在指令碼執行期間重定向某個特定檔案描述符
echo "this is error line" >&2
echo "this is normal line"

4.在指令碼中重定向輸入
#!/bin/bash
exec 0< stdin.txt
while read line                           read命令不再從標準輸入(預設鍵盤)中讀取,而從檔案中讀取
do 
   echo "$line"
done

5.建立新的輸出檔案描述符
#!/bin/bash
exec 3>&1                                 檔案描述符3重定向到檔案描述符1,即顯示器
exec 1> testfile                          檔案描述符1重定向至testfile檔案
echo "this is a line should be in testfile"

exec 1>&3                                 檔案描述符1重定向到檔案描述符3,即回到顯示器

echo "back to normal"

6.建立新的輸入檔案描述符
#!/bin/bash
exec 6<&0                                 將STDIN檔案描述符儲存到檔案描述符6

exec 0< stdin.txt

while read line
do 
   echo "$line"
done
 
exec 0<&6                                  恢復檔案描述符0為從顯示器中讀取資料
read -p "enter your name:"
echo "your name $REPLY"

7.關閉檔案描述符
exec 3>&-                                  指令碼結束前手動關閉檔案描述符

8.列出開啟的檔案描述符
# lsof -a -p $$ -d 0,1,2
COMMAND   PID USER   FD   TYPE DEVICE SIZE NODE NAME
bash    20371 root    0u   CHR  136,3         5 /dev/pts/3
bash    20371 root    1u   CHR  136,3         5 /dev/pts/3
bash    20371 root    2u   CHR  136,3         5 /dev/pts/3
FD:檔案描述符數目及訪問型別(r讀,w寫,u讀寫)
NAME:檔名,標準輸出即終端裝置名
$$:特殊環境變數,程序的當前PID

9.阻止命令輸出
# ls -al > /dev/null                        null檔案不儲存任何資料
# cat /dev/null > testfile                  清空檔案同時不刪除檔案的好辦法

三、建立臨時檔案
1.建立臨時本地檔案
# mktemp tempfile.XXXXXX                         檔名末尾加6個X
tempfile.V22488

2.建立/tmp目錄下的臨時檔案
# mktemp -t tempfile.XXXXXX
/tmp/tempfile.A22529

3.建立臨時目錄
# mktemp -t -d tempdir.XXXXXX
/tmp/tempdir.v22556

四、記錄訊息
1.tee命令
# date | tee tee.txt                             顯示器顯示訊息的同時,記錄到tee.txt檔案
# date | tee -a tee.txt                          -a選項,追加到檔案