1. 程式人生 > 實用技巧 >輸入輸出

輸入輸出

目錄

重定向概述

什麼是重定向

將原本要輸出到螢幕的資料資訊,重新定向到某個指定的檔案中。比如:每天凌晨定時備份資料,希望將備份資料的結果儲存到某個檔案中。這樣第二天通過檢視檔案的內容就知道昨天備份的資料是成功還是失敗。

重定向作用

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

標準輸入與輸出

當執行一個程式時通常會自動開啟三個標準檔案,分別是標準輸入、標準輸出、錯誤輸出


程序將從標準輸入中得到資料,將正常輸出列印至螢幕終端,將錯誤的輸出資訊也列印至螢幕終端。

以 cat 命令為例, cat 命令的功能是從命令列給出的檔案中讀取資料,並將這些資料直接送到標準輸出。若使用如下命令:

#會把檔案/etc/passwd的內容輸出顯示到螢幕上
[root@lqz ~]# cat /etc/passwd

但如果 使用 cat 命令沒有跟上輸入的檔名,那麼cat命令則會通過命令列標準輸入中讀取資料, 並將其送到標準輸出。

[root@lqz ~]# cat
hello   #標準輸入
hello   #標準輸出
^C
#使用者輸入的每一行都立刻被cat命令輸出到螢幕上。

#持續追蹤檢視檔案內容
[root@lqz ~]# tail -f /etc/passwd
ctrl+z 將程序轉到後臺

#檢視執行的程序
[root@lqz ~]# ps
PID TTY          TIME CMD
5848 pts/1    00:00:00 bash
6885 pts/1    00:00:00 tail
6888 pts/1    00:00:00 ps

#檢視tail命令的pid,6885程序下的檔案描述符
[root@lqz ~]# ls -l /proc/6885/fd
total 0
lrwx------ 1 root root 64 Dec  3 06:57 0 -> /dev/pts/1
lrwx------ 1 root root 64 Dec  3 06:57 1 -> /dev/pts/1
lrwx------ 1 root root 64 Dec  3 06:56 2 -> /dev/pts/1
lr-x------ 1 root root 64 Dec  3 06:57 3 -> /etc/passwd
lr-x------ 1 root root 64 Dec  3 06:57 4 -> inotify

#Linux檢視標準輸入輸出裝置
[root@lqz ~]# 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

輸出重定向

輸出重定向,改變輸出內容的位置

標準輸出重定向(每次都會覆蓋檔案)

#標準輸出重定向, 先清空,後寫入, 如果檔案不存在則建立
[root@lqz ~]# ifconfig eth0 > abc

標準輸出重定向(會往檔案的尾部在新增內容)

#標準追加輸出重定向, 向配置檔案末尾追加內容
[lqz@lqz ~]$ echo "This is network conf" >> if

錯誤輸出重定向

#正確輸出以及錯誤輸出重定向至一個檔案
[root@lqz ~]# useradd lqz
[root@lqz ~]# su - lqz

#將標準輸出和標準錯誤輸出重定向到不同檔案
[lqz@lqz ~]$ find /etc -name ".conf" 1>a 2>b

正確和錯誤都輸入到相同位置

#將標準輸出和標準錯誤輸出重定向到同一個檔案, 混合輸出
[lqz@lqz ~]$ find /etc -name ".conf" &>ab

#合併兩個檔案內容至一個檔案
[lqz@lqz ~]$ cat a b > c

正確和錯誤都輸入到相同位置

#重定向到相同的位置
[root@lqz ~]# ls /root /error >ab  2>&1

重定向到空裝置/dev/null

#將產生的任何資料放入黑洞裝置,則視為丟棄。
[root@lqz ~]# ls /root /error >ab 2>/dev/null
[root@lqz ~]# ls /root /error >ab &>/dev/null

指令碼中使用重定向

[root@lqz ~]# vim ping.sh 
ping -c1 10.0.0.1
if [ $? -eq 0 ];then
    echo "10.0.0.1 is up." 
else
    echo "10.0.0.1 is down." 
fi
[root@lqz ~]# chmod +x ping.sh 
[root@lqz ~]# ./ping.sh

#改進後版
[root@lqz ~]# vim ping.sh
ping -c1 10.0.0.1 &>/dev/null
if [ $? -eq 0 ];then
    echo "10.0.0.1 is up." 
else
    echo "10.0.0.1 is down." 
fi

輸入重定向

輸入重定向,即原本從鍵盤等上獲得的輸入資訊,重定向由命令的輸出作為輸入。< 等價 0<

從檔案中讀入輸入的操作

#沒有改變輸入的方向,預設鍵盤
[root@lqz ~]# mail alice 
Subject: hello
1111 
2222
3333
.   #結束
EOT

#檢查是否收到郵件
[root@lqz ~]# su - alice
[root@lqz ~]# mail

#輸入重定向,來自於檔案
[root@lqz ~]# mail -s "test01" alice < /etc/hosts

#沒有改變輸入的方向,預設鍵盤,此時等待輸入
[root@lqz ~]# grep 'root' 
xxx
xxx

[root@lqz ~]# grep 'root' < /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@lqz ~]# dd if=/dev/zero of=/file1.txt bs=1M count=20
[root@lqz ~]# dd </dev/zero >/file2.txt bs=1M count=20

資料庫備份

[root@lqz ~]# mysql -uroot -p123 < bbs.sql

利用重定向建立多行資料的檔案

#手動執行 shell 命令
[root@lqz ~]# echo "111" > file1.txt 
[root@lqz ~]# cat file1.txt
111
[root@lqz ~]# cat >file2.txt
111
222
333
^D

[root@lqz ~]# cat >>file3.txt
aaa
bbb
ccc
^D

指令碼中列印選單

[root@lqz ~]# vim vm.sh
cat <<-EOF
+------------------- --- ---- --- ---- --- --- ---- --- --+ ||
| ====================== | 
| 虛擬機器基本管理 v5.0 |
| by lqz |
| ====================== | 
| 1. 安裝 KVM |
| 2. 安裝或重置 CentOS-6.9 | 
| 3. 安裝或重置 CentOS-7.4 | 
| 5. 安裝或重置 Windows-7  | 
| 6. 刪除所有虛擬機器 |
| q. 退出管理程式 |
+------------------- --- ---- --- ---- --- --- ---- --- --+ 
EOF

兩條命令同時重定向

[root@lqz ~]# ls; date &>/dev/null
[root@lqz ~]# ls &>/dev/null; date &>/dev/null
[root@lqz ~]# (ls; date) &>/dev/null

#後臺執行
[root@lqz ~]# (while :; do date; sleep 2; done) &
[1] 6378
[root@lqz ~]# (while :; do date; sleep 2; done) &>date.txt &
[root@lqz ~]# jobs
[1]+ 執行中 ( while :; do date; sleep 2;
done ) &>/date.txt &

程序管道技術

管道操作符號 “|” ,主要用來連線左右兩個命令, 將左側的命令的標準輸出, 交給右側命令的標準輸入

將/etc/passwd 中的使用者按 UID 大小排序

[root@lqz ~]# sort -t":" -k3 -n /etc/passwd
[root@lqz ~]# sort -t":" -k3 -n /etc/passwd -r
[root@lqz ~]# sort -t":" -k3 -n /etc/passwd |head

統計當前/etc/passwd 中使用者使用的 shell 型別

#思路:取出第七列(shell) | 排序(把相同歸類)| 去重
[root@lqz ~]# awk -F: '{print $7}' /etc/passwd
[root@lqz ~]# awk -F: '{print $7}' /etc/passwd |sort
[root@lqz ~]# awk -F: '{print $7}' /etc/passwd |sort |uniq
[root@lqz ~]# awk -F: '{print $7}' /etc/passwd |sort |uniq -c

統計網站的訪問情況 top 20

#思路: 列印所有訪問的連線 | 過濾訪問網站的連線 | 列印使用者的 IP | 排序 | 去重

[root@lqz ~]# yum -y install httpd
[root@lqz ~]# systemctl start httpd
[root@lqz ~]# systemctl stop firewalld

[root@lqz ~]# ss -an |grep :80 |awk -F":" '{print $8}' |sort |uniq -c
[root@lqz ~]# ss -an |grep :80 |awk -F":" '{print $8}' |sort |uniq -c |sort -k1 -rn |head -n 20

列印當前所有 IP

[root@lqz ~]# ip addr |grep 'inet ' |awk '{print $2}' |awk -F"/" '{print $1}'
127.0.0.1
192.168.69.112

列印根分割槽已用空間的百分比

[root@lqz ~]# df |grep '/$' |awk '{print $5}' |awk -F"%" '{print $1}'

管道中的tee技術

#選項: -a追加
[root@lqz ~]# ip addr |grep 'inet ' |tee ip.txt |awk -F"/" '{print $1}' |awk '{print $2}'
127.0.0.1
10.0.0.100

[root@lqz ~]# cat ip.txt
inet 127.0.0.1/8 scope host lo
inet 10.0.0.100/24 brd 192.168.69.255 scope global ens32
[root@lqz ~]# date > date.txt    #直接將內容寫入date.txt檔案中
[root@lqz ~]# date |tee date.txt #命令執行會輸出至螢幕,但會同時儲存一份至date.txt檔案中

# xargs引數傳遞,主要讓一些不支援管道的命令可以使用管道技術
# which cat|xargs ls- l
# ls |xargs rm -fv
# ls |xargs cp -rvt /tmp/ -或-> ls | xargs -I {} cp -rv {} /tmp/
# ls |xargs mv -t /tmp/   -或-> ls | xargs -I {}  mv {} /tmp