Linux重定向
重定向概述:
什么是重定向:
Linux中的重定向就是將原本要輸出到屏幕中的數據信息,重新指向某個特定文件當中,或者定向到黑洞文件(/dev/null)中。
重定向的作用:
- 當屏幕輸出的信息很重要,希望保存時
- 后台執行的程序一般都會有輸出,不希望它輸出干擾到終端
- 執行定時備份任務,希望將備份結果保留下來時
- 執行一些命令,會提示一些報錯信息,可以直接將報錯丟棄。
- 執行命令時希望將報錯和正確內容區分在不同文件中時(日志)
命令返回值(拓展)
在Linux下,不管是啟動桌面程序還是執行命令,所有程序在結束時都會返回一個數字值,這個值叫做返回值,或者稱為錯誤號。
[root@localhost ~]# ls
[root@localhost ~]# echo $?
0
我們執行ls命令,通過echo$?,打印$?的值,我們發現返回值是0
返回值是0,則代表上一條命令執行成功返回值
非0,則代表上一條命令執行不成功
文件描述符
li可以理解為linux跟蹤打開文件,而分配的一個數字,這個數字有點類似c語言操作文件時候的句柄,通過句柄就可以實現文件的讀寫操作。 用戶可以自定義文件描述符范圍是:3-num,這個最大數字,跟用戶的:ulimit –n 定義數字有關系,不能超過最大值。
linux啟動后,會默認打開3個文件描述符,分別是:標准輸入standard input 0,正確輸出standard output 1,錯誤輸出:error output 2。以后打開文件后。新增文件綁定描述符可以依次增加。 一條shell命令執行,都會繼承父進程的文件描述符。因此,所有運行的shell命令,都會有默認3個文件描述符。
名稱 | 文件描述符 | 作用 |
---|---|---|
標准輸入(stdin) | 0 | 通常是鍵盤,也可以是其他文件或者命令的輸出的內容可以作為標准輸入 |
標准輸出(stdout) | 1 | 默認輸出到屏幕 |
錯誤輸出(stderr) | 2 | 默認輸出到屏幕 |
文件名稱(filename) | 3+ |
-
當進程操作一個文件時:
- 首先程序是無法直接訪問硬件,需要借助內核來訪問文件
- 而內核kernel需要利用文件描述(file descriptor)來訪問
-
總結:進程使用文件描述符來管理打開的文件對應關系
-
通常程序訪問一個文件至少會打開三個標准文件,分別是標准輸入,標准輸出,錯誤輸出
-
進程將從標准輸入中的到數據,將正常輸出打印至屏幕終端,將錯誤的輸出信息也打印至屏幕終端
輸入輸出符號及作用
名稱 | 符號 | 作用 |
---|---|---|
標准輸入重定向 | <或者0< | 將符號右邊的內容交給符號左邊的命令 |
標准輸出覆蓋重定向 | >或者1> | 將原本要輸出在屏幕上的正確內容,覆蓋到重定向的文件中 |
標准輸出追加重定向 | >>或者1>> | 將原本要輸出在屏幕上的正確內容,追加到重定向的文件中 |
錯誤輸出覆蓋重定向 | 2> | 將原本要輸出在屏幕上的錯誤內容,覆蓋到重定向的文件中 |
錯誤輸出追加重定向 | 2>> | 將原本要輸出在屏幕上的錯誤內容,追加到重定向的文件中 |
案例1:標准輸出覆蓋重定向
- 標准輸出重定向示例
- 如果文件不存在則創建
- 如果文件存在則清空內容,后寫入
[root@localhost ~]# ifconfig eth0 > abc
案例2:標准輸出追加重定向
- 標准輸出重定向示例
- 如果文件不存在則創建
- 如果文件存在則在文件尾部添加內容
[root@localhost ~]# echo "This is network conf" >> if
案例3:錯誤輸出重定向
- 錯誤輸出重定向示例
- 正確輸出及錯誤輸出至相同文件
- 正確輸出及錯誤輸出至不同的文件
[root@localhost ~]#find /etc -name "*.conf" 1>ok 2>error
案例4:混合和輸出重定向
- 錯誤輸出重定向示例
- 將正確輸出和錯誤輸出混合至同一文件
- 將兩個文件內容組合為一個文件
#將標准輸出和標准錯誤輸出重定向到同一個文件, 混合輸出
1.[root@localhost ~]# find /etc -name "*.conf" &>ab
2.[root@localhost ~]# find /etc -name "*.conf" >ab 2>&1
#合並兩個文件內容至一個文件
[root@localhost ~]# cat a b > c
案例5:將內容輸出至黑洞
[root@localhost ~]# ls /root/error>ab 2>/dev/null
[root@localhost ~]# ls /root/error>ab &>/dev/null
案例6:輸入重定向
1.
#沒有改變輸入的方向,默認鍵盤,此時等待輸入
[root@localhost ~]# grep 'root'
xxx
xxx
[root@localhost ~]# grep 'root' < /etc/passwd
root:x:0:0:root:/root:/bin/bash
2.
[root@localhost ~]# dd if=/dev/zero of=/file1.txt bs=1M count=20
[root@localhost ~]# dd </dev/zero >/file2.txt bs=1M count=20
案例7:利用重定向建立多行的文件
[root@localhost ~]# vim fruit.sh
#!/bin/sh
menu(){
cat <<EOF
+------------+
| 1 | apple |
+---+--------+
| 2 | pear |
+---+--------+
| 3 | banana |
+---+--------+
| 4 | cherry |
+---+--------+
EOF
read -p "please input a num: " fruit
}
usage(){
echo "USAGE:請輸入水果編號"
exit 1
}
color(){
case "$fruit" in
1)
echo -e "\E[1;31mapple \E[0m"
;;
2)
echo -e "\E[1;20mpear \E[0m"
;;
3)
echo -e "\E[1;33mbanana \E[0m"
;;
4)
echo -e "\E[1;35mcherry \E[0m"
;;
*)
usage
esac
}
menu
color
輸入輸出過程檢測
#持續追蹤查看文件內容
[root@localhost ~]# tail -f /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
lw:x:1000:1000::/home/lw:/bin/bash
lw1:x:1001:1001::/home/lw1:/bin/bash
oldboy:x:615:1002::/home/oldboy:/bin/bash
^Z (ctrl+z 將進程轉到后台)
[1]+ Stopped tail -f /etc/passwd
#查看運行的進程
[root@localhost ~]# ps
PID TTY TIME CMD
8217 pts/1 00:00:00 bash
8258 pts/1 00:00:00 tail
8259 pts/1 00:00:00 ps
#查看8258進程下的文件描述符
[root@localhost ~]# ls -l /proc/8258/fd
total 0
lrwx------. 1 root root 64 Apr 13 19:25 0 -> /dev/pts/1
lrwx------. 1 root root 64 Apr 13 19:25 1 -> /dev/pts/1
lrwx------. 1 root root 64 Apr 13 19:25 2 -> /dev/pts/1
lr-x------. 1 root root 64 Apr 13 19:25 3 -> /etc/passwd
lr-x------. 1 root root 64 Apr 13 19:25 4 -> anon_inode:inotify
# Linux查看標准輸入輸出設備
[root@localhost ~]# ls -l /dev/std*
lrwxrwxrwx 1 root root 15 Dec 2 22:30 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Dec 2 22:30 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Dec 2 22:30 /dev/stdout -> /proc/self/fd/1
補充:Linux重定向&符
$ command > file 2>&1
$ command >> file 2>&1
這里的&沒有固定的意思
放在>后面的&,表示重定向的目標不是一個文件,而是一個文件描述符。
換言之 2>1 代表將stderr重定向到當前路徑下文件名為1的regular file中,而2>&1代表將stderr重定向到文件描述符為1的文件(即/dev/stdout)中,這個文件就是stdout在file system中的映射
而&>file是一種特殊的用法,也可以寫成>&file,二者的意思完全相同,都等價於
>file 2>&1