Linux Shell筆記之輸入與輸出
阿新 • • 發佈:2019-01-11
一、獲取輸入
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選項,追加到檔案
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
[
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 "
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
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選項,追加到檔案