1. 程式人生 > 實用技巧 >第十六章 輸出輸入重定向,管道技術

第十六章 輸出輸入重定向,管道技術

輸出輸入

重定向


什麼是重定向
將一些資訊重定向到一個指定的地方,或者從一個重定向的位置讀取內容。

為什麼使用重定向?
1.當螢幕輸出的資訊很重要,而且希望儲存重要的資訊時;
2.後臺執行中的程式,不希望他干擾螢幕正常的輸出結果時;
3.系統的例行命令, 例如定時任務的執行結果,希望可以存下來時;
4.一些執行命令,我們已經知道他可能出現錯誤資訊, 想將他直接丟棄時;
5.錯誤日誌與正確日誌需要分別輸出至不同的檔案儲存時;


[root@lxy ~]# ll /dev/st*
lrwxrwxrwx. 1 root root 15 Nov 28 18:49 /dev/stderr -> /proc/self/fd/2 #錯誤輸出 2> 2>> 不能省略
lrwxrwxrwx. 1 root root 15 Nov 28 18:49 /dev/stdin -> /proc/self/fd/0 #標準輸入 < << 0 可以省略
lrwxrwxrwx. 1 root root 15 Nov 28 18:49 /dev/stdout -> /proc/self/fd/1 #標準輸出 > >> 1 可以省略


#檢視程式的進行過程中產生的一些檔案
[root@lxy ~]# tail -f /var/log/messages
Dec 19 15:01:01 lxy systemd: Created slice User Slice of root.
Dec 19 15:01:01 lxy systemd: Started Session 538 of user root.
Dec 19 15:01:01 lxy systemd: Removed slice User Slice of root.
Dec 19 16:01:01 lxy systemd: Created slice User Slice of root.
Dec 19 16:01:01 lxy systemd: Started Session 539 of user root.


^Z
[1]+ Stopped tail -f /var/log/messages #將程序轉至後臺
[root@lxy ~]# ps
PID TTY TIME CMD
97761 pts/0 00:00:00 su
97767 pts/0 00:00:00 bash
97968 pts/0 00:00:00 tail
97974 pts/0 00:00:00 ps

[root@lxy ~]# ll /proc/97968/fd/
total 0
lrwx------. 1 root root 64 Dec 19 16:25 0 -> /dev/pts/0
lrwx------. 1 root root 64 Dec 19 16:25 1 -> /dev/pts/0
lrwx------. 1 root root 64 Dec 19 16:24 2 -> /dev/pts/0
lr-x------. 1 root root 64 Dec 19 16:25 3 -> /var/log/messages
lr-x------. 1 root root 64 Dec 19 16:25 4 -> anon_inode:inotify

#Linux檢視標準輸入輸出裝置

[root@lxy ~]# 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

stderr #標準錯誤輸出 2 預設輸出到螢幕上面
stdin #標準輸入 0 預設是由鍵盤或者從命令或者檔案中讀取
stdout #標準輸出 1 預設輸出到螢幕上面


[root@lxy ~]# cat
oldboy #標準輸入,沒有指定檔案時,預設從鍵盤中讀取資料
oldboy #標準輸出,將你標準輸入的結果進行標準輸出到螢幕上面

輸出重定向

作用:將輸出的結果重定向到一個指定的位置中,(不管正確的資訊或者錯誤的資訊)

> 標準輸出重定向,作用:覆蓋原始檔的內容,將新的正確的內容寫入到檔案中,如果檔案不存在,會自動建立。

>> 標準輸出追加重定向,作用:不會覆蓋原始檔的內容,會將新正確的的內容追加到檔案的底部,如果檔案不存在,會自動建立。

2> 標準錯誤輸出重定向,作用:覆蓋原始檔的內容,將新的錯誤的資訊重定向到檔案中,如果檔案不存在,會自動建立。

2>> 標準錯誤輸出追加重定向,作用:不會覆蓋原始檔的內容,將新的錯誤的資訊追加到檔案的底部,如果檔案不存在,會自動建立。


案例1: 標準輸出重定向

[root@lxy ~]# echo hello
hello
[root@lxy ~]# echo hello >file1.txt #標準輸出重定向, 先清空,後寫入, 如果檔案不存在則建立
[root@lxy ~]# cat file1.txt
hello
[root@lxy ~]# cat file1.txt /etc/passwd >file2.txt
[root@lxy ~]# cat file2.txt
hello
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@lxy ~]# cat file1.txt >file3.txt #合併兩個檔案,將兩個檔案的輸出重新定向到一個新的檔案中
[root@lxy ~]# cat file3.txt
hello
[root@lxy ~]# cat >file4.txt
oldboy
oldgirl
^C
[root@lxy ~]# cat file4.txt
oldboy
oldgirl
[root@lxy ~]# cat >>file4.txt
linux
^C
[root@lxy ~]# cat file4.txt
oldboy
oldgirl
linux

案例2:標準輸出追加重定向

[root@lxy ~]# echo 'test' >>file1.txt #向配置檔案末尾追加內容
[root@lxy ~]# cat file1.txt
hello
test

案例3:標準錯誤輸出重定向
[root@lxy ~]# ls /rttt >file5.txt
ls: cannot access /rttt: No such file or directory
[root@lxy ~]# cat file5.txt
[root@lxy ~]# ls /rttt 2>file5.txt #錯誤的輸出每次會覆蓋檔案中的內容,正確的內容不會輸出
[root@lxy ~]# cat file5.txt
ls: cannot access /rttt: No such file or directory
[root@lxy ~]# ls /root 2>file5.txt
file1.txt file2.txt file3.txt file4.txt file5.txt


案例4:標準錯誤輸出追加重定向

[root@lxy ~]# ls /rttt 2>>file5.txt #錯誤的輸出會往檔案的尾部在新增內容
[root@lxy ~]# cat file5.txt
ls: cannot access /rttt: No such file or directory
ls: cannot access /rttt: No such file or directory
[root@lxy ~]# ls /rttt 2>>file5.txt
[root@lxy ~]# cat file5.txt
ls: cannot access /rttt: No such file or directory
ls: cannot access /rttt: No such file or directory
ls: cannot access /rttt: No such file or directory
[root@lxy ~]# ls /root 2>>file5.txt
file1.txt file2.txt file3.txt file4.txt file5.txt
[root@lxy ~]# cat file5.txt
ls: cannot access /rttt: No such file or directory
ls: cannot access /rttt: No such file or directory
ls: cannot access /rttt: No such file or directory

案例5:將錯誤和正確的都重定向到一個檔案中

[root@lxy ~]# ls /rttt >file6.txt 2>&1 #不推薦
[root@lxy ~]# ls /root >file6.txt 2>&1
[root@lxy ~]# cat file6.txt
file1.txt
file2.txt
file3.txt

[root@lxy ~]# ls /rttt &>file6.txt #推薦寫法
[root@lxy ~]# cat file6.txt
ls: cannot access /rttt: No such file or directory
[root@lxy ~]# ls /root &>file6.txt
[root@lxy ~]# cat file6.txt
file1.txt
file2.txt
file3.txt

[root@lxy ~]# cat file6.txt
ls: cannot access /rot: No such file or directory
[root@lxy ~]# ls /rot &>>file6.txt
[root@lxy ~]# cat file6.txt
ls: cannot access /rot: No such file or directory
ls: cannot access /rot: No such file or directory
[root@lxy ~]# ls /root &>>file6.txt
[root@lxy ~]# cat file6.txt
ls: cannot access /rot: No such file or directory
ls: cannot access /rot: No such file or directory
file1.txt
file2.txt
file3.txt


案例6: 將輸出的資訊定向到空

[root@lxy ~]# ls /root
file1.txt file2.txt file3.txt file4.txt file5.txt file6.txt
[root@lxy ~]# echo $?
0
[root@lxy ~]# ls /root >/dev/null
[root@lxy ~]# cat /dev/null
[root@lxy ~]# ls /rtt 2>/dev/null
[root@lxy ~]# ls /rtt &>/dev/null
[root@lxy ~]# ls /root &>/dev/null


案例7: 將正確的輸出資訊和錯誤的輸出資訊重定向不同的檔案中

[root@lxy ~]# ls /opt/ 2>file7.txt
services
[root@lxy ~]# ls /opt/ >file7.txt 2>file8.txt
[root@lxy ~]# rm -rf /opt/
[root@lxy ~]# ls /opt/ >file7.txt 2>file8.txt
[root@lxy ~]# cat file7.txt
[root@lxy ~]# cat file8.txt
ls: cannot access /opt/: No such file or directory

[root@lxy ~]# ls /opt/ >>file7.txt 2>>file8.txt
[root@lxy ~]# rm -rf /opt/
[root@lxy ~]# ls /opt/ >>file7.txt 2>>file8.txt
[root@lxy ~]# cat file7.txt
services
[root@lxy ~]# cat file8.txt
ls: cannot access /opt/: No such file or directory
ls: cannot access /opt/: No such file or directory

案例8:多條命令的輸出結果到檔案中

[root@lxy ~]# ls ;ls /mnt >file9.txt
file1.txt file2.txt file3.txt file4.txt file5.txt file6.txt file7.txt file8.txt
[root@lxy ~]# ls /mnt/
data data9.txt data.log test.log test.txt
[root@lxy ~]# ls >>file9.txt ;ls /mnt >>file9.txt
[root@lxy ~]# cat file9.txt
data
data9.txt
data.log
test.log
file1.txt
file2.txt
file3.txt

[root@lxy ~]# (ls /root;ls /mnt) >>file10.txt
[root@lxy ~]# cat file10.txt
file10.txt
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt

案例9: 指令碼中使用重定向

[root@lxy ~]# cat test.sh
#!/bin/bash
ping -c1 www.baidu.com

if [ $? -eq 0 ];then
echo "網路是通暢的....."
else
echo "網路是不通的....."
fi
[root@lxy ~]# ./test.sh
PING www.a.shifen.com (180.101.49.12) 56(84) bytes of data.
64 bytes from 180.101.49.12 (180.101.49.12): icmp_seq=1 ttl=128 time=17.8 ms

--- www.a.shifen.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 17.818/17.818/17.818/0.000 ms
網路是通暢的.....

[root@lxy ~]# cat test.sh
#!/bin/bash
ping -c1 www.baidu.com &>/dev/null

if [ $? -eq 0 ];then
echo "網路是通暢的....."
else
echo "網路是不通的....."
fi
[root@lxy ~]# ./test.sh
網路是通暢的.....

輸入重定向

將預設從鍵盤上面輸入的內容改為從命令中或者檔案讀取內容


< #標準輸入重定向, 作用:將預設從鍵盤上面讀取內容改為從命令或者檔案讀取內容

<< #標準輸入限定識別符號重定向。作用:標準輸入內容,直到遇到識別符號的分解符結束


案例1:標準輸入重定向

[root@lxy ~]# cat < file1.txt
hello
test
file1.txt
file2.txt
file3.txt
file4.txt
[root@lxy ~]# cat
root
root
^C
[root@lxy ~]# tr 'f' 'F'
file
File
^C
[root@lxy ~]# tr 'f' 'F' <file1.txt
hello
test
File1.txt
File2.txt
File3.txt
File4.txt

[root@lxy ~]# grep 'root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@lxy ~]# grep 'root' < /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@lxy ~]# grep 'root'
oldboy
root
root
rootttt
rootttt
^C

案例2:資料庫中匯入庫或者表,恢復資料

[root@lxy ~]# mysql -uroot -p123 < database.sql

案例3:生成一個檔案

dd #生成一個大檔案
if #從哪裡讀取資料
of #輸出到哪裡
bs #一次輸出多少
count #輸出的次數

[root@lxy ~]# dd if=/dev/zero of=/root/test.log bs=10M count=100
100+0 records in
100+0 records out
1048576000 bytes (1.0 GB) copied, 27.5536 s, 38.1 MB/s
[root@lxy ~]# ll -h
total 1001M
-rw-r--r--. 1 root root 143 Dec 19 17:34 file10.txt
-rw-r--r--. 1 root root 1000M Dec 19 18:27 test.log
-rwxr-xr-x. 1 root root 143 Dec 19 17:38 test.sh
[root@lxy ~]# dd </dev/zero >/root/test.txt bs=10M count=10
10+0 records in
10+0 records out
104857600 bytes (105 MB) copied, 11.6617 s, 9.0 MB/s
[root@lxy ~]# ll -h
total 1.1G
-rw-r--r--. 1 root root 143 Dec 19 17:34 file10.txt
-rw-r--r--. 1 root root 1000M Dec 19 18:27 test.log
-rwxr-xr-x. 1 root root 143 Dec 19 17:38 test.sh
-rw-r--r--. 1 root root 100M Dec 19 18:28 test.txt

案例4:標準輸入限定識別符號重定向

[root@lxy ~]# cat >new.txt<<EOF
> oldboy
> oldgirl
> EOF
[root@lxy ~]# cat new.txt
oldboy
oldgirl

案例5:指令碼中使用標準輸入限定識別符號重定向

指令碼中列印選單

[root@lxy ~]# cat ./test.sh
#!/bin/bash
cat <<EOF
-rw-r--r--. 1 root root 143 Dec 19 17:34 file10.txt
-rw-r--r--. 1 root root 51 Dec 19 17:12 file1.txt
-rw-r--r--. 1 root root 2.2K Dec 19 17:05 file2.txt
EOF
ping -c1 www.baidu.com &>/dev/null

if [ $? -eq 0 ];then
echo "網路是通暢的....."
else
echo "網路是不通的....."
fi

[root@lxy ~]# ./test.sh
-rw-r--r--. 1 root root 143 Dec 19 17:34 file10.txt
-rw-r--r--. 1 root root 51 Dec 19 17:12 file1.txt
-rw-r--r--. 1 root root 2.2K Dec 19 17:05 file2.txt
網路是通暢的.....

管道技術

作用:將左側的命令的輸出結果作為右側命令的標準輸入進行處理,不會把錯誤的資訊傳遞過去


cmd1 | cmd2 | cmd3 ......

案例:


[root@lxy ~]# cut -d ":" -f3 /etc/passwd | sort -rn
2022
2021
2020
2019

[root@lxy ~]# cut -d ":" -f7 /etc/passwd | sort | uniq -c | sort -rn
28 /bin/bash
19 /sbin/nologin
1 /sbin/shutdown
1 /sbin/halt
1 /bin/sync

[root@lxy ~]# ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:ae:0b:8a brd ff:ff:ff:ff:ff:ff
inet 10.0.0.100/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::c653:602a:38c6:e45/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@lxy ~]# ip a s eth0 | grep -w inet
inet 10.0.0.100/24 brd 10.0.0.255 scope global noprefixroute eth0
[root@lxy ~]# ip a s eth0 | grep -w inet | cut -d " " -f6
10.0.0.100/24
[root@lxy ~]# ip a s eth0 | grep -w inet | cut -d " " -f6 | cut -d "/" -f1
10.0.0.100

管道技術中的tee技術

管道技術中的tee技術

作用:將輸出結果輸出到螢幕的同時,也會輸出到一個指定的檔案中

-a #追加

[root@lxy ~]# ip a s eth0 | grep -w inet | cut -d " " -f6 | cut -d "/" -f1 | tee ip.txt
10.0.0.100
[root@lxy ~]# cat ip.txt
10.0.0.100
[root@lxy ~]# ip a s eth0 | grep -w inet | cut -d " " -f6 | cut -d "/" -f1 > ip.txt
[root@lxy ~]# cat ip.txt
10.0.0.100
[root@lxy ~]# echo $RANDOM|md5sum | cut -c 1-10
2139cee1fc
[root@lxy ~]# echo $RANDOM|md5sum | cut -c 1-10 |passwd --stdin user06
Changing password for user user06.
passwd: all authentication tokens updated successfully.
[root@lxy ~]# echo $RANDOM|md5sum | cut -c 1-10 |tee pass.txt |passwd --stdin user06
Changing password for user user06.
passwd: all authentication tokens updated successfully.
[root@lxy ~]# echo $RANDOM|md5sum | cut -c 1-10 |tee |passwd --stdin user06
Changing password for user user06.
passwd: all authentication tokens updated successfully.
[root@lxy ~]# echo $RANDOM|md5sum | cut -c 1-10 |tee pass.txt
c3d3da1a5e
[root@lxy ~]# echo $RANDOM|md5sum | cut -c 1-10 |tee -a pass.txt
a026eeb93c
[root@lxy ~]# cat pass.txt
c3d3da1a5e
a026eeb93c

xargs

xargs   #將一些不支援管道命令支援管道,預設管道是將左側的輸出結果標準輸入到右側的命令,主要是針對資料操作,xargs可以讓這些資料交給右側命令當做是針對檔案操作。


[root@lxy ~]# ls | rm -rf
[root@lxy ~]# ls
file10.txt file2.txt file4.txt file6.txt file8.txt ip.txt pass.txt test.sh
file1.txt file3.txt file5.txt file7.txt file9.txt new.txt test.log test.txt
[root@lxy ~]# ls |xargs rm -rf

[root@lxy ~]# for i in {1..10} ;do echo 'oldboy' >file$i.txt ;done
[root@lxy ~]# ll
total 40
-rw-r--r--. 1 root root 7 Dec 19 19:09 file10.txt
-rw-r--r--. 1 root root 7 Dec 19 19:09 file1.txt
-rw-r--r--. 1 root root 7 Dec 19 19:09 file2.txt
-rw-r--r--. 1 root root 7 Dec 19 19:09 file3.txt
[root@lxy ~]# cat ./*
oldboy
oldboy
oldboy
[root@lxy ~]# ls | sed 's#oldboy#oldgirl#g'
file10.txt
file1.txt
file2.txt
[root@lxy ~]# ls |xargs sed 's#oldboy#oldgirl#g'
oldgirl
oldgirl
oldgirl
[root@lxy ~]# ls |xargs sed 's#oldboy#oldgirl#g' -i
[root@lxy ~]# cat ./*
oldgirl
oldgirl
oldgirl
[root@lxy ~]# find ./ -name "*.txt"
./file8.txt
./file9.txt
./file10.txt
[root@lxy ~]# find ./ -name "*.txt" -ls
67560148 4 -rw-r--r-- 1 root root 8 Dec 19 19:11 ./file8.txt
67738439 4 -rw-r--r-- 1 root root 8 Dec 19 19:11 ./file9.txt
67753461 4 -rw-r--r-- 1 root root 8 Dec 19 19:11 ./file10.txt
[root@lxy ~]# find ./ -name "*.txt" | ls -l
total 40
-rw-r--r--. 1 root root 8 Dec 19 19:11 file10.txt
-rw-r--r--. 1 root root 8 Dec 19 19:11 file1.txt
-rw-r--r--. 1 root root 8 Dec 19 19:11 file2.txt
[root@lxy ~]# touch 123.log
[root@lxy ~]# find ./ -name "*.txt" | ls -l
total 40
-rw-r--r--. 1 root root 0 Dec 19 19:13 123.log
-rw-r--r--. 1 root root 8 Dec 19 19:11 file10.txt
-rw-r--r--. 1 root root 8 Dec 19 19:11 file1.txt
[root@lxy ~]# find ./ -name "*.txt" |xargs ls -l
-rw-r--r--. 1 root root 8 Dec 19 19:11 ./file10.txt
-rw-r--r--. 1 root root 8 Dec 19 19:11 ./file1.txt
-rw-r--r--. 1 root root 8 Dec 19 19:11 ./file2.txt

#將當前目錄下的所有.txt型別的檔案複製到/opt目錄
[root@lxy ~]# find ./ -name "*.txt" |xargs cp -t /opt
[root@lxy ~]# ll /opt
total 40
-rw-r--r--. 1 root root 8 Dec 19 19:15 file10.txt
-rw-r--r--. 1 root root 8 Dec 19 19:15 file1.txt
-rw-r--r--. 1 root root 8 Dec 19 19:15 file2.txt

[root@lxy ~]# cp $(find ./ -name "*.txt") /opt/
[root@lxy ~]# ll /opt/
total 40
-rw-r--r--. 1 root root 8 Dec 19 19:17 file10.txt
-rw-r--r--. 1 root root 8 Dec 19 19:17 file1.txt
-rw-r--r--. 1 root root 8 Dec 19 19:17 file2.txt