《學習bash》筆記--輸入輸出

來源:互聯網
上載者:User

《學習bash》筆記--輸入輸出
1.I/O重新導向符

I/O重新導向符如下:

cmd1 | cmd2:管道,接收cmd1的標準輸出作為cmd2的標準輸入。 >file:將標準輸出定向到file <file:從file接收標準輸入 >>file:將標準輸出定向到file,如果file存在則附加在後面 >|file:即使設定了noclobber仍然強制標準輸出到file。

shell提供了一種稱為noclobber的特性,該特性可防止重新導向時不經意地重寫了已存在的檔案。通過設定變數noclobber可以

將此特 性開啟。開啟後若將輸出重新導向到某個已存在檔案,則shell將報告錯誤訊息,並且不執行重新導向命令。

例如:

root@-virtual-machine:~# cat a.txt
123
root@virtual-machine:~# set -o | grep "noclobber"
noclobber off
root@virtual-machine:~# echo "test1" > a.txt
root@virtual-machine:~# cat a.txt
test1
root@virtual-machine:~# set -o noclobber
root@virtual-machine:~# set -o | grep "noclobber"
noclobber on
root@gmdz-virtual-machine:~# echo "hello" > a.txt
-bash: a.txt: 無法覆蓋已存在的檔案

root@virtual-machine:~# echo "hello" >| a.txt
root@virtual-machine:~# cat a.txt
hello

n>|file:即使設定了noclobber仍強制從檔案描述符n中輸出到file。

例如:

root@-virtual-machine:~# cat a.txt
123
root@virtual-machine:~# set -o | grep "noclobber"
noclobber off
root@virtual-machine:~# ls nosuchfile 2> a.txt
root@virtual-machine:~# cat a.txt
ls: 無法訪問nosuchfile: 沒有那個檔案或目錄
root@virtual-machine:~# echo "123" > a.txt
root@virtual-machine:~# cat a.txt
123
root@virtual-machine:~# set -o noclobber
root@virtual-machine:~# set -o | grep "noclobber"
noclobber on
root@virtual-machine:~# ls nosuchfile 2> a.txt
-bash: a.txt: 無法覆蓋已存在的檔案
root@virtual-machine:~# cat a.txt
123
root@virtual-machine:~# ls nosuchfile 2>| a.txt
root@virtual-machine:~# cat a.txt
ls: 無法訪問nosuchfile: 沒有那個檔案或目錄

<>file:使用file同時作為輸入和輸出。主要用於裝置檔案,也就是對應諸如終端和通訊線路的硬體裝置,底層系統程式員可以使用它測試裝置磁碟機,否則,它不是很有用。 n<>file,以讀寫方式開啟file,並將n重新導向到該檔案。

要說明這個重新導向符之前,先要說明exec命令:

shell的內建命令exec將並不啟動新的shell,而是用要被執行命令替換當前的shell進程,並且將老進程的環境清理掉,而且exec命令

後的其它命令將不再執行。因此,如果你在一個shell裡面,執行exec ls那麼,當列出了目前的目錄後,這個shell就自己退出了,因為這個

shell進程已被替換為僅僅執行ls命令的一個進程,執行結束自然也就退出了。不過,要注意一個例外,當exec命令來對檔案描述符操

作的時候,就不會替換shell,而且操作完成後,還會繼續執行接下來的命令。

  1. $ exec 3<>file
  2. $ ls >&3
  3. $ cat file
  4. file
  5. $ cat <&3
  6. $ exec 3<>file
  7. $ cat <&3
  8. 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\

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.