file 將檔案描述符3定向到file,然後把標準輸出定向到3以後,標準輸出的內容就寫入到file中。同樣從標準輸入讀的時候,將標準輸入定向
到3,會列印出file的內容。由上面的結果還能看到exec 3<> file只針對一條指令有效。
n>file,以寫式開啟file,並將n重新導向到該檔案。
例如:
root@gmdz-virtual-machine:~/test# exec 3> file
root@gmdz-virtual-machine:~/test# ls >& 3
root@gmdz-virtual-machine:~/test# cat file
a
b
root@gmdz-virtual-machine:~/test# cat <& 3
cat: -: 錯誤的檔案描述符
n<file,以讀式開啟file,並將n重新導向到該檔案。
例如:
root@virtual-machine:~/test# cat file
test
root@virtual-machine:~/test# exec 3< file
root@virtual-machine:~/test# ls >& 3
ls: 寫入錯誤: 錯誤的檔案描述符
root@virtual-machine:~/test# cat <& 3
test
root@virtual-machine:~/test# cat <& 3
root@virtual-machine:~/test#
同樣,exec 3< file只針對一條指令有效。
<<label:here-document
<<label重新導向符強制一個命令的輸入使用shell的標準輸入,並一直讀到僅含label的行。期間的輸入稱為here-document
例如:
# cat > msgfile << EOF
> 1
> 2
> 3
> EOF
root@gmdz-virtual-machine:~/test# cat msgfile
1
2
3
重新導向<<有兩個變體,首先,你可以通過把label括在單引號或雙引號內防止shell進行參數和命令替換,例如:
root@virtual-machine:~/test# cat << EOF
> $PWD
> EOF
/root/test
root@virtual-machine:~/test# cat << "EOF"
> $PWD
> EOF
$PWD
第二個變體是<<-,它從here-document和標籤行中刪除前置TAB(但不刪除空格)。
例如指令碼內容如下:
#!/bin/bash
cat <<- EOF
123
456
EOF
執行後,輸出為:
123
456
n>> file:將檔案描述符n定向到file,如果file存在則附加到後面,例如:command 2>> filen>& :將標準輸出複製到檔案描述符n
n<& :從檔案描述符n複製標準輸入
n>&m:使檔案描述符n成為輸出檔案描述符m的副本
例如:
root@virtual-machine:~/test# cat file
test
root@virtual-machine:~/test# ls nosuchfile
ls: 無法訪問nosuchfile: 沒有那個檔案或目錄
root@virtual-machine:~/test# ls nosuchfile > file 2>&1
root@virtual-machine:~/test# cat file
ls: 無法訪問nosuchfile: 沒有那個檔案或目錄
n<&m:使檔案描述符n成為輸入檔案描述符m的副本&>file:定向標準輸出和錯誤輸出到file。
例如:
root@virtual-machine:~/test# ll a nosuchfile &> file
root@virtual-machine:~/test# cat file
ls: 無法訪問nosuchfile: 沒有那個檔案或目錄
-rw-r--r-- 1 root root 0 2014-08-01 09:09 a
<&-:關閉標準輸入
例如有如下指令碼:
exec <&-
cat
執行結果:
# ./a.sh
cat: -: 錯誤的檔案描述符
cat: 關閉標準輸入: 錯誤的檔案描述符
>&-:關閉標準輸出
例如有如下指令碼:
exec >&-
echo "test"
執行結果:
# ./a.sh
./a.sh: 第 2 行: echo: 寫錯誤: 錯誤的檔案描述符
n>&-:關閉從檔案描述符n的輸出
例如:
root@gmdz-virtual-machine:~# ls
a.sh file test
root@virtual-machine:~# exec 3<> file
root@virtual-machine:~# ls >&3
root@virtual-machine:~# exec 3<> file
root@virtual-machine:~# exec 3>&-
root@virtual-machine:~# ls >&3
-bash: 3: 錯誤的檔案描述符
n<&-:關閉從檔案描述符n的輸入
例如:
root@gmdz-virtual-machine:~# exec 3<> file
root@gmdz-virtual-machine:~# cat <&3
a.sh
file
test
root@virtual-machine:~# exec 3<> file
root@virtual-machine:~# exec 3<&-
root@virtual-machine:~# cat <&3
-bash: 3: 錯誤的檔案描述符
2.字串I/O2.1.echo
echo將其參數簡單地列印到標準輸出上。echo接收短劃線選項,如下表。
-e:開啟斜線逸出字元的解釋
-E:關閉子系統上反斜線逸出字元的解釋,此為預設模式。
-n:省略最後的換行
例如:
root@virtual-machine:~# echo -e "a\ta"
a a
root@virtual-machine:~# echo -E "a\ta"
a\ta
root@virtual-machine:~# echo -n "a\ta"
a\taroot@virtual-machine:~#
2.2.read
read允許你將值讀到shell變數中,基本文法是:
read var1 var2 ...
該語句從標準輸入中接收一行,將其分開形成單詞,單詞間用環境變數IFS的值中的任一字元分隔。單詞然後被賦值到變數
var1,var2...
例如,a.sh的內容為:
read v1 v2
echo $v1
echo $v2
執行結果:
# ./a.sh
123 456
123
456
如果單詞比變數多,則額外的單詞被賦值到最後的變數中,如果你省略了變數,則整個輸入被賦值到變數REPLY中。
例如,再次執行上面的指令碼:
# ./a.sh
1 2 3 4
1
2 3 4
修改a.sh的內容為:
read
echo $REPLY
執行結果為:
# ./a.sh
1 2 3 4
1 2 3 4
下面介紹如下從檔案中讀取變數。
例如,file檔案內容如下:
arg1-1 arg1-2
arg2-1 arg2-2
arg3-1 arg3-2
方法一:
使用如下a.sh指令碼可以進行變數的讀取:
while read v1 v2;do
echo $v1 $v2
done
執行結果:
# ./a.sh < file
arg1-1 arg1-2
arg2-1 arg2-2
arg3-1 arg3-2
方法二:
修改a.sh:
while read v1 v2;do
echo $v1 $v2
done < file
執行結果:
# ./a.sh
arg1-1 arg1-2
arg2-1 arg2-2
arg3-1 arg3-2
方法三:
修改a.sh:
func(){
while read v1 v2;do
echo $v1 $v2
done
}
func < file
執行結果:
# ./a.sh
arg1-1 arg1-2
arg2-1 arg2-2
arg3-1 arg3-2
方法四:
修改a.sh:
{
while read v1 v2;do
echo $v1 $v2
done
} < file
執行結果:
# ./a.sh
arg1-1 arg1-2
arg2-1 arg2-2
arg3-1 arg3-2
read有3個常用選項:-a,-p和-r。
-a允許你將值讀到一個數組中,每個連續的條目讀取都被賦值到以下標0開始的給定數組中,例如a.sh內容如下:
read -a people
echo ${people[0]} ${people[1]} ${people[2]}
執行結果:
# ./a.sh
1 2 3
1 2 3
-p選項在讀取輸入前列印該字串,例如:
[root@yanPC ~]# read -p "dir?" dirname
dir?/home
[root@yanPC ~]# echo $dirname
/home
-r選項在讀取輸入時不忽略“\”字元。
如果"\"在輸入字串的內部:
[root@yanPC ~]# read dirname
123\456
[root@yanPC ~]# echo $dirname
123456
[root@yanPC ~]# read -r dirname
123\456
[root@yanPC ~]# echo $dirname
123\456
如果"\"在輸入字串的最後:
[root@yanPC ~]# read dirname
123\
> 456
[root@yanPC ~]# echo $dirname
123456
[root@yanPC ~]# read -r dirname
123\
[root@yanPC ~]# echo $dirname
123\