![]() |
![]() |
![]() |
![]() |
![]() |
$ cat ex1.sh #!/bin/bash # read〝FILE.txt〞 line by line while read -r line #←此行是我看起來怪怪的地方之一,〝read〞是讀鍵盤怎可讀檔案? do echo $line done <FILE.txt #←此行是我看起來怪怪的地方之二,〝done <FILE〞是什麼東東??? |
$ cat ex2.sh #!/bin/bash while read -r line do echo $line read -p "Press any key to continue" -n 1 #←我增加的行 done <FILE.txt |
fd Number | Name | Function |
0 | stdin | 標準輸入 |
1 | stdout | 標準輸出 |
2 | stderr | 標準錯誤 |
Function | Example | Example note | |
COMMAND 1> | stdout 重定向 | echo '123' >fileA | fd 1 輸往檔案 |
COMMAND 1>> | stdout 累加重定向 | seq 100 200 >> fileA | fd 1 累加輸往檔案 |
COMMAND 2> | stderr 重定向 | find / -name '*.conf' 2>/dev/null | fd 2 輸往檔案 |
COMMAND 2>> | stderr 累加重定向 | seq 1 10 >>fileA | fd 2 累加輸往檔案 |
COMMAND 0< | stdin 重定向 | cat < fileA | fd 0 由檔案取代 |
Function | Example | |
2>&1 | stderr(2) 重定向 stdout(1) | ls -R /home > fileA 2>&1 |
1>&2 | stdout 重定向 stderr | find / -name '*readme.txt' 1>&2 2>/dev/null |
$ seq 1 1000000 1 2 3 4 Ctrl+Z ←按 <Ctrl+Z>暫停 [1]+ Stopped seq 1 100000000 ←程式被 stoped 了 $ jobs -p ←列出被我們暫停的指令的 PID $ 2373 ←剛那指令〝seq 1 1000000〞 PID 為 2373 ls -lgG /proc/2373/fd/ ←列出 /proc/<PID>/fd 來觀察 fd 使用情形 total 0 lrwx------ 1 64 2015-04-26 22:28 0 -> /dev/tty1 lrwx------ 1 64 2015-04-26 22:28 1 -> /dev/tty1 lrwx------ 1 64 2015-04-26 22:28 2 -> /dev/tty1 |
lrwx------ 1 64 2015-04-26 15:04 0 -> /dev/tty1 l-wx------ 1 64 2015-04-26 15:04 1 -> /home/basalt/fileA l-wx------ 1 64 2015-04-26 15:04 2 -> /home/basalt/fileA |
$ exec 8>/tmp/fd_test ←建立 fd 8 並重定向到檔案〝tmp/fd_test〞 $ echo $$ ←查看目前 shell 的 PID 2633 ←目前 shell 的 PID $ ls -lgG /proc/2633/fd ←觀查 fd 的使用 total 0 lr-x------ 1 64 2015-05-04 10:17 0 -> /dev/tty1 l-wx------ 1 64 2015-05-04 10:17 1 -> /dev/tty1 l-wx------ 1 64 2015-05-04 10:17 2 -> /dev/tty1 lrwx------ 1 64 2015-05-04 10:58 255 -> /dev/tty1 lr-x------ 1 64 2015-05-04 10:17 8 -> /tmp/fd_test ← fd 8 建立並重定向到檔案 |
$ echo 'hello world !' >&8 ←將字串寫入 fd 8 $ cat /tmp/fd_test ←驗證看看 hello world ! |
$ cat ex3.sh #!/bin/bash # flowing create fd 3~5 and redirect to file1~file3 exec 3>/tmp/file1 exec 4>/tmp/file2 exec 5>/tmp/file3 # flowing write string to fd1 then redirect to fd 3~5 echo '1234' >&3 echo 'abcd' >&4 echo 'I II III IV' >&5 # flowing close fd 3~5 exec 3>&- exec 4>&- exec 5>&- |
$ exec 6>&1 ←fd 6 重定向到 fd 1 $ ls -l /root /etc/fstab 2>&1 1>&6 | tr a-z A-Z ← stderr 經 pipe 給 tr 轉大寫 -rw-r--r-- 1 root root 608 2014-09-26 15:47 /etc/fstab ← stdout 部分沒轉大寫因重定向到 fd 6 LS: CANNOT OPEN DIRECTORY /ROOT: PERMISSION DENIED ← stderr 部分被 tr 轉大寫 $ exec 6>&- ←關閉 fd 6 |
$ cat ex4.sh #!/bin/bash exec < /etc/fstab #fd 0 (stdin)= file〝/etc/fstab〞 # flowing read〝/etc/fstab〞 line1~3 read line1 read line2 read line3 # flowing print〝/etc/fstab〞 line1~3 echo $line1 echo $line2 echo $line3 |
$ cat ex5.sh #!/bin/bash # read file "/etc/fstab" line by line exec 0< /etc/fstab # fd 0 (stdin) = file while read line # now command read from file instead of stdin do echo $line done |
$ exec 3>/tmp/fd_test ←將 fd 3 重定向到檔案〝tmp/fd_test〞 $ echo "line1" >&3 ←將字串寫入 fd 3 $ cat /tmp/fd_test ←驗證看看 line1 $ exec 9<&3 ← 開啟 fd9,並將 fd 3 重定向到 fd 9(此時 fd 9 就等於 fd 3) $ echo "line2" >&9 ←將字串寫入 fd 9 $ cat /tmp/fd_test ←驗證看看 line1 line2 $ exec 9>&- ←關閉 fd 9 $ exec 3<&- ←關閉 fd 3 |
$ echo 1234567890 > File ←建一檔案〝File〞 $ exec 3<> File ←打開檔案〝File〞並重定向到 fd 3 $ read -n 4 <&3 ←讀第 4 個字元 $ echo -n "." >&3 ←寫入句點〝.〞 $ exec 3>&- ←關閉 fd 3 $ cat File ←驗證看看 1234.67890 |
$ find / -name 'readme.*' 2>&- ←找 filesystem 內所有叫〝readme.*〞的檔案 & 關閉 stderr /usr/share/icons/Bluecurve/48x48/mimetypes/readme.png /usr/share/doc/cyrus-sasl-lib-2.1.22/readme.html /usr/share/doc/words-3.0/readme.txt /usr/share/icons/Bluecurve/48x48/mimetypes/readme.png |
$ exec 6>&1 $ ls -l /root /etc/fstab 2>&1 1>&6 6>&- | tr a-z A-Z 6>&- ←此處的〝6>&-〞是暫時關閉 fd 6 for tr $ exec 6>&- ←此處是永久關閉 shell 的 fd 6 |
lr-x------ 1 64 2015-04-26 14:45 0 -> /home/basalt/FILE.txt ←stdin 變檔案 lrwx------ 1 64 2015-04-26 14:45 1 -> /dev/tty1 lrwx------ 1 64 2015-04-26 14:45 10 -> /dev/tty1 ←多開啟了 fd 10 lrwx------ 1 64 2015-04-26 14:45 2 -> /dev/tty1 lr-x------ 1 64 2015-04-26 14:45 255 -> /home/basalt/ex1.sh |
exec 10<&0 #←shell 隱藏操作的部分 (備份 fd 0 到 fd10) exec < FILE.txt #←shell 隱藏操作的部分(stdin=file) while read -r line do echo $line done #←原始指令為 done<FILE.txt exec 0<&10 #←shell 隱藏的部分 (從 fd 10 復原 fd 0) |
$ cat ex6.sh #!/bin/bash # read〝FILE.txt〞 line by line exec 7<FILE.txt # ← fd 7=FILE.txt) while read -u 7 line #← read 讀取由 stdin 改為 fd 7) do echo $line read -p "Press any key to continue" -n 1 done |
$ cat ex7.sh #!/bin/bash while read file_name do rm -iv $file_name done < <(ls) |
$ cat ex8.sh |