Linux的哲學

一、常用的指令

1.壓縮命令

tar -czvf 壓縮包名稱.tar.gz 要打包的目錄

2.解壓縮命令

tar -xzvf 壓縮包名稱.tar.gz

3.find命令

如果要想獲取到該目錄中所有以 host 開頭的文件列表,可以執行如下命令:

find /etc -name "host*" -print

如果要在整個系統中搜索權限中包括 SUID 權限的所有文件(詳見第 5 章),只需使用-4000 即可:

find / -perm -4000 -print

4.export命令

將一個變量指定為全局變量

WORKDIR=/home/workdir
export WORKDIR

5.curl ifconfig.me

查詢本機的公網ip

5.更改文件的所有者

chown -Rf ftp /var/ftp/pub

5.指定文件只能自己查看

chmod 600 auth.smb

二、重定向

1.輸入重定向與管道符

符號 作用
命令 < 文件 將文件作為命令的標準輸入
命令 << 分界符 從標準輸入中讀入,直到遇見分界符才停止
命令 < 文件 1 > 文件 2 文件 2 將文件 1 作為命令的標準輸入并將標準輸出到文件 2

2.輸出重定向

符號 作用
命令 > 文件 將標準輸出重定向到一個文件中(清空原有文件的數據)
命令 2> 文件 將錯誤輸出重定向到一個文件中(清空原有文件的數據)
命令 >> 文件 將標準輸出重定向到一個文件中(追加到原有內容的后面)
命令 2>> 文件 將錯誤輸出重定向到一個文件中(追加到原有內容的后面)
命令 >> 文件 2>&1或命令 &>> 文件 將標準輸出與錯誤輸出共同寫入到文件中(追加到原有內容的后面)

3.管道符

將上一個命令的輸出傳遞給下一個命令的輸入,如在重置root的密碼時

echo "linuxprobe" | passwd --stdin root

4.通配符

星號(*)代表匹配零個或多個字符,問號(?)代表匹配單個字符,中括號內加上數字[0-9]代表匹配 0~9 之間的單個數字的字符,而中括號內加上字母[abc]則是代表匹配 a、 b、 c 三個字符中的任意一個字符。

匹配所有在/dev 目錄中且以 sda 開頭的文件:

[root@linuxprobe ~]# ls -l /dev/sda*
brw-rw----. 1 root disk 8, 0 May 4 15:55 /dev/sda
brw-rw----. 1 root disk 8, 1 May 4 15:55 /dev/sda1
brw-rw----. 1 root disk 8, 2 May 4 15:55 /dev/sda2

如果只想查看文件名為 sda 開頭,但是后面還緊跟其他某一個字符的文件的相關信息,該怎么操作呢?這時就需要用到問號來進行通配了。

[root@linuxprobe ~]# ls -l /dev/sda?
brw-rw----. 1 root disk 8, 1 May 4 15:55 /dev/sda1
brw-rw----. 1 root disk 8, 2 May 4 15:55 /dev/sda2

除了使用[0-9]來匹配 0~9 之間的單個數字,也可以用[135]這樣的方式僅匹配這三個指定數字中的一個,若沒有匹配到,則不會顯示出來:

[root@linuxprobe ~]# ls -l /dev/sda[0-9]
brw-rw----. 1 root disk 8, 1 May 4 15:55 /dev/sda1
brw-rw----. 1 root disk 8, 2 May 4 15:55 /dev/sda2
[root@linuxprobe ~]# ls -l /dev/sda[135]
brw-rw----. 1 root disk 8, 1 May 4 15:55 /dev/sda1

5.常用的轉義字符

4 個最常用的轉義字符如下所示。
? 反斜杠(\):使反斜杠后面的一個變量變為單純的字符串。
? 單引號(''):轉義其中所有的變量為單純的字符串。
? 雙引號(""):保留其中的變量屬性,不進行轉義處理。
? 反引號(``):把其中的命令執行后返回結果

6.重要的環境變量

用戶執行了一條命令之后, Linux 系統中到底發生了什么事情呢?簡單來說,命令在 Linux 中的執行分為 4 個步驟。

第1步:判斷用戶是否以絕對路徑或相對路徑的方式輸入命令(如/bin/ls),如果是的話則直接執行。

第2步: Linux 系統檢查用戶輸入的命令是否為“別名命令”,即用一個自定義的命令名稱來替換原本的命令名稱。可以用 alias 命令來創建一個屬于自己的命令別名,格式為“alias 別名=命令”。若要取消一個命令別名,則是用 unalias 命令,格式為“unalias 別名”。

我們之前在使用 rm 命令刪除文件時,Linux 系統都會要求我們再確認是否執行刪除操作,其實這就是 Linux系統為了防止用戶誤刪除文件而特意設置的 rm 別名命令,接下來我們把它取消掉:

[root@linuxprobe ~]# ls
anaconda-ks.cfg Documents initial-setup-ks.cfg Pictures Templates
Desktop Downloads Music Public Videos
[root@linuxprobe ~]# rm anaconda-ks.cfg
rm: remove regular file ‘anaconda-ks.cfg’? y
[root@linuxprobe~]# alias rm
alias rm='rm -i'
[root@linuxprobe ~]# unalias rm
[root@linuxprobe ~]# rm initial-setup-ks.cfg
[root@linuxprobe ~]#

第3步: Bash 解釋器判斷用戶輸入的是內部命令還是外部命令。內部命令是解釋器內部的指令,會被直接執行;而用戶在絕大部分時間輸入的是外部命令,這些命令交由步驟 4 繼續處理。可以使用“type 命令名稱”來判斷用戶輸入的命令是內部命令還是外部命令。

第4步:系統在多個路徑中查找用戶輸入的命令文件,而定義這些路徑的變量叫作 PATH, 可以簡單地把它理解成是“解釋器的小助手”,作用是告訴 Bash 解釋器待執行的命令可能存放的位置,然后 Bash 解釋器就會乖乖地在這些位置中逐個查找。 PATH 是由多個路徑值組成的變量,每個路徑值之間用冒號間隔,對這些路徑的增加和刪除操作將影響到 Bash 解釋器對Linux 命令的查找。

[root@linuxprobe ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
[root@linuxprobe ~]# PATH=$PATH:/root/bin
[root@linuxprobe ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin

三、軟件的配置

1、配置yum倉庫

第1步:進入到/etc/yum.repos.d/目錄中(因為該目錄存放著 Yum 軟件倉庫的配置文件)。

第2步: 使用 Vim 編輯器創建一個名為 rhel7.repo 的新配置文件(文件名稱可隨意,但后綴必須為.repo),逐項寫入下面加粗的配置參數并保存退出(不要寫后面的中文注釋)。
? 【rhel-media】: Yum 軟件倉庫唯一標識符,避免與其他倉庫沖突。
? 【name=linuxprobe】: Yum 軟件倉庫的名稱描述,易于識別倉庫用處。
? 【baseurl=file://media/cdrom】: 提供的方式包括 FTP(ftp://..)、 HTTP(http://..)、本地(file:///..)。
? 【enabled=1】: 設置此源是否可用; 1 為可用, 0 為禁用。
? 【gpgcheck=1】: 設置此源是否校驗文件; 1 為校驗, 0 為不校驗。
? 【gpgkey=file://media/cdrom/RPM-GPG-KEY-redhat-release】: 若上面參數開啟校驗,那么請指定公鑰文件地址。

第3步:按配置參數的路徑掛載光盤,并把光盤掛載信息寫入到/etc/fstab 文件中。

第4步:使用“yum install httpd -y”命令檢查 Yum 軟件倉庫是否已經可用。進入/etc/yum.repos.d 目錄中后創建 Yum 配置文件:

[root@linuxprobe ~]# cd /etc/yum.repos.d/
[root@linuxprobe yum.repos.d]# vim rhel7.repo
[rhel7]
name=rhel7
baseurl=file:///media/cdrom
enabled=1
gpgcheck=0

創建掛載點后進行掛載操作,并設置成開機自動掛載(詳見第 6 章)。 嘗試使用 Yum 軟件倉庫來安裝 Web 服務,出現 Complete! 則代表配置正確:

[root@linuxprobe yum.repos.d]# mkdir -p /media/cdrom
[root@linuxprobe yum.repos.d]# mount /dev/cdrom /media/cdrom
mount: /dev/sr0 is write-protected, mounting read-only
[root@linuxprobe yum.repos.d]# vim /etc/fstab
/dev/cdrom /media/cdrom iso9660 defaults 0 0
[root@linuxprobe ~]# yum install httpd
Loaded plugins: langpacks, product-id, subscription-manager
………………省略部分輸出信息………………
Dependencies Resolved
===============================================================================
Package Arch Version Repository Size
===============================================================================
Installing:
httpd x86_64 2.4.6-17.el7 rhel 1.2 M
Installing for dependencies:
apr x86_64 1.4.8-3.el7 rhel 103 k
apr-util x86_64 1.5.2-6.el7 rhel 92 k
httpd-tools x86_64 2.4.6-17.el7 rhel 77 k
mailcap noarch 2.1.41-2.el7 rhel 31 k
Transaction Summary
===============================================================================
Install 1 Package (+4 Dependent packages)
Total download size: 1.5 M
Installed size: 4.3 M
Is this ok [y/d/N]: y
Downloading packages:
………………省略部分輸出信息………………
Complete!

四、Shell腳本

可以將 Shell 終端解釋器當作人與計算機硬件之間的“翻譯官”,它作為用戶與 Linux 系統內部的通信媒介,除了能夠支持各種變量與參數外,還提供了諸如循環、分支等高級編程語言才有的控制結構特性。

#!/bin/bash
#For Example BY linuxprobe.com
pwd
ls -al

在上面的這個 example.sh 腳本中實際上出現了三種不同的元素:

  • 第一行的腳本聲明(#!)用來告訴系統使用哪種 Shell 解釋器來執行該腳本;
  • 第二行的注釋信息(#)是對腳本功能和某些命令的介紹信息,使得自己或他人在日后看到這個腳本內容時,可以快速知道該腳本的作用或一些警告信息;
  • 第三、四行的可執行語句也就是我們平時執行的 Linux 命令了。

1. 接收用戶的參數

腳本:
#!/bin/bash
echo "當前腳本名稱為$0"
echo "總共有$#個參數,分別是$*。 "
echo "第 1 個參數為$1,第 5 個為$5。 "

運行:
[root@linuxprobe ~]# sh example.sh one two three four five six
當前腳本名稱為 example.sh
總共有 6 個參數,分別是 one two three four five six。
第 1 個參數為 one,第 5 個為 five。

2. 判斷用戶的參數

按照測試對象來劃分,條件測試語句可以分為 4 種:
? 文件測試語句;
? 邏輯測試語句;
? 整數值比較語句;
? 字符串比較語句。

文件測試所用的參數:

運算符 作用
-d 測試文件是否為目錄類型
-e 測試文件是否存在
-f 判斷是否為一般文件
-r 測試當前用戶是否有權限讀取
-w 測試當前用戶是否有權限寫入
-x 測試當前用戶是否有權限執行

可用的整數比較運算符

運算符 作用
-eq 是否等于
-ne 是否不等于
-gt 是否大于
-lt 是否小于
-le 是否等于或小于
-ge 是否大于或等于

流程控制語句

1. if 條件測試語句

雙分支的測試語句:

#!/bin/bash
ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
if [ $? -eq 0 ]
then
echo "Host $1 is On-line."
else
echo "Host $1 is Off-line."
fi

多分支的測試語句:

#!/bin/bash
read -p "Enter your score(0-100): " GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then
echo "$GRADE is Excellent"
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
echo "$GRADE is Pass"
else
echo "$GRADE is Fail"
fi
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100): 88
88 is Excellent
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100): 80
80 is Pass
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100): 30
30 is Fail
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100): 200
200 is Fail

2. for 條件循環語句

#!/bin/bash
read -p "Enter The Users Password : " PASSWD
for UNAME in `cat users.txt`
do
id $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "Already exists"
else
useradd $UNAME &> /dev/null
echo "$PASSWD" | passwd --stdin $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "$UNAME , Create success"
else
echo "$UNAME , Create failure"
fi
fi
done

運行上面的腳本:

[root@linuxprobe ~]# bash Example.sh
Enter The Users Password : linuxprobe
andy , Create success
barry , Create success
carl , Create success
duke , Create success
eric , Create success
george , Create success

3. while 條件循環語句

#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品實際價格為 0-999 之間,猜猜看是多少? "
while true
do
read -p "請輸入您猜測的價格數目: " INT
let TIMES++
if [ $INT -eq $PRICE ] ; then
echo "恭喜您答對了,實際價格是 $PRICE"
echo "您總共猜測了 $TIMES 次"
exit 0
elif [ $INT -gt $PRICE ] ; then
echo "太高了! "
else
echo "太低了! "
fi
done

4.case 條件測試語句

#!/bin/bash
read -p "請輸入一個字符,并按 Enter 鍵確認: " KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您輸入的是 字母。 "
;;
[0-9])
echo "您輸入的是 數字。 "
;;
*)
echo "您輸入的是 空格、功能鍵或其他控制字符。 "
esac

運行以上腳本:

[root@linuxprobe ~]# bash Checkkeys.sh
請輸入一個字符,并按 Enter 鍵確認: 6
您輸入的是 數字。
[root@linuxprobe ~]# bash Checkkeys.sh
請輸入一個字符,并按 Enter 鍵確認: p
您輸入的是 字母。
[root@linuxprobe ~]# bash Checkkeys.sh
請輸入一個字符,并按 Enter 鍵確認: ^[[15~
您輸入的是 空格、功能鍵或其他控制字符。

計劃任務服務程序

計劃任務分為一次性計劃任務與長期性計劃任務:
? 一次性計劃任務:今晚 11 點 30 分開啟網站服務。
? 長期性計劃任務:每周一的凌晨 3 點 25 分把/home/wwwroot 目錄打包備份為backup.tar.gz。

例如,使用下述命令將系統設置為在今晚 23:30 分自動重啟網站服務。

[root@linuxprobe ~]# at 23:30
at > systemctl restart httpd
at > 此處請同時按下 Ctrl + D 組合鍵來結束編寫計劃任務
job 3 at Mon Apr 27 23:30:00 2017
[root@linuxprobe ~]# at -l

如果想挑戰一下難度更大但簡捷性更高的方式,可以把前面學習的管道符(任意門)放到兩條命令之間,讓 at 命令接收前面 echo 命令的輸出信息,以達到通過非交互式的方式創建計劃一次性任務的目的

[root@linuxprobe ~]# echo "systemctl restart httpd" | at 23:30
job 4 at Mon Apr 27 23:30:00 2017
[root@linuxprobe ~]# at -l
3 Mon Apr 27 23:30:00 2017 a root
4 Mon Apr 27 23:30:00 2017 a root

如果我們不小心設置了兩個一次性計劃任務,可以使用下面的命令輕松刪除其中一個:

[root@linuxprobe ~]# atrm 3
[root@linuxprobe ~]# at -l
4 Mon Apr 27 23:30:00 2017 a root

定時語句的語法:

使用 crond 設置任務的參數字段說明:

運算符 作用
取值為 0~59 的整數
取值為 0~23 的任意整數
取值為 1~31 的任意整數
取值為 1~12 的任意整數
星期 取值為 0~7 的任意整數,其中 0 與 7 均為星期日
命令 要執行的命令或程序腳本

假設在每周一、三、五的凌晨 3 點 25 分,都需要使用 tar 命令把某個網站的數據目錄進行打包處理,使其作為一個備份文件。我們可以使用 crontab -e 命令來創建計劃任務。為自己創建計劃任務無需使用-u 參數,具體的實現效果的參數如 crontab -l 命令結果所示:

[root@linuxprobe ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@linuxprobe ~]# crontab -l
25 3 * * 1,3,5 /usr/bin/tar -czvf backup.tar.gz /home/wwwroot

需要說明的是,除了用逗號(,)來分別表示多個時間段,例如“8,9,12”表示 8 月、 9 月和 12 月。還可以用減號(-)來表示一段連續的時間周期(例如字段“日”的取值為“12-15”,則表示每月的 12~15 日)。以及用除號(/)表示執行任務的間隔時間(例如“/2”表示每隔2 分鐘執行一次任務)。如果在 crond 服務中需要同時包含多條計劃任務的命令語句,應每行僅寫一條。尤其需要注意的是,在 crond 服務的計劃任務參數中,所有命令一定要用絕對路徑的方式來寫,如果不知道絕對路徑,請用 whereis 命令進行查詢。*

注意點:

? 在 crond 服務的配置參數中,可以像 Shell 腳本那樣以#號開頭寫上注釋信息,這樣
在日后回顧這段命令代碼時可以快速了解其功能、需求以及編寫人員等重要信息。
? 計劃任務中的“分”字段必須有數值,絕對不能為空或是*號,而“日”和“星期”字
段不能同時使用,否則就會發生沖突

五、用戶和組

1. 常用的一些命令

useradd 命令:

參數 作用
-d 指定用戶的家目錄(默認為/home/username)
-e 賬戶的到期時間,格式為 YYYY-MM-DD.
-u 指定該用戶的默認 UID
-g 指定一個初始的用戶基本組(必須已存在)
-G 指定一個或多個擴展用戶組
-N 不創建與用戶同名的基本用戶組
-s 指定該用戶的默認 Shell 解釋器

實例:

[root@linuxprobe ~]# useradd -d /home/linux -u 8888 -s /sbin/nologin linuxprobe
[root@linuxprobe ~]# id linuxprobe
uid=8888(linuxprobe) gid=8888(linuxprobe) groups=8888(linuxprobe)

groupadd 命令:

groupadd 命令用于創建用戶組,格式為“groupadd [選項] 群組名”。

[root@linuxprobe ~]# groupadd ronny

usermod 命令:

usermod 命令用于修改用戶的屬性,格式為“usermod [選項] 用戶名”。

參數 作用
-c 填寫用戶賬戶的備注信息
-d -m 參數-m 與參數-d 連用,可重新指定用戶的家目錄并自動把舊的數據轉移過去
-e 賬戶的到期時間,格式為 YYYY-MM-DD
-g 變更所屬用戶組
-G 變更擴展用戶組
-L 鎖定用戶禁止其登錄系統
-U 解鎖用戶,允許其登錄系統
-s 變更默認終端
-u 修改用戶的 UID

將用戶 linuxprobe 加入到 root 用戶組中,這樣擴展組列表中則會出現 root 用戶組的
字樣,而基本組不會受到影響,如下:

[root@linuxprobe ~]# usermod -G root linuxprobe
[root@linuxprobe ~]# id linuxprobe
uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)

passwd 命令:

passwd 命令用于修改用戶密碼、過期時間、認證信息等,格式為“passwd [選項] [用戶名]”。

參數 作用
-l 鎖定用戶,禁止其登錄
-u 解除鎖定,允許用戶登錄
--stdin 允許通過標準輸入修改用戶密碼,如 echo "NewPassWord" | passwd --stdin Username
-d 使該用戶可用空密碼登錄系統
-e 強制用戶在下次登錄時修改密碼
-S 顯示用戶的密碼是否被鎖定,以及密碼所采用的加密算法名稱
[root@linuxprobe ~]# passwd
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@linuxprobe ~]# passwd linuxprobe
Changing password for user linuxprobe.
New password:
Retype new password:
passwd: all authentication tokens updated successfully

假設您有位同事正在度假,而且假期很長,那么可以使用 passwd 命令禁止該用戶登錄系統,等假期結束回歸工作崗位時,再使用該命令允許用戶登錄系統,而不是將其刪除。這樣既保證了這段時間內系統的安全,也避免了頻繁添加、刪除用戶帶來的麻煩:

[root@linuxprobe ~]# passwd -l linuxprobe
Locking password for user linuxprobe.
passwd: Success
[root@linuxprobe ~]# passwd -S linuxprobe
linuxprobe LK 2017-12-26 0 99999 7 -1 (Password locked.)
[root@linuxprobe ~]# passwd -u linuxprobe
Unlocking password for user linuxprobe.
passwd: Success
[root@linuxprobe ~]# passwd -S linuxprobe
linuxprobe PS 2017-12-26 0 99999 7 -1 (Password set, SHA512 crypt.)

userdel 命令:

userdel 命令用于刪除用戶,格式為“userdel [選項] 用戶名”。

參數 作用
-f 強制刪除用戶
-r 同時刪除用戶及用戶家目錄

2.文件權限與歸屬

盡管在 Linux 系統中一切都是文件,但是每個文件的類型不盡相同,因此 Linux 系統使
用了不同的字符來加以區分,常見的字符如下所示。

字符 含義
- 普通文件。
d 目錄文件。
l 鏈接文件。
b 塊設備文件。
c 字符設備文件。
p 管道文件。

對于一般文件來說,權限比較容易理解;但是,對于目錄文件來說,理解其權限設置來就不那么容易了。很多資深 Linux 用戶其實也沒有真正搞明白。他們的區別對比如下表:

字符 文件含義 目錄含義
可讀(r) 表示能夠讀取文件的實際內容; 表示能夠讀取目錄內的文件列表
可寫(w) 表示能夠編輯、新增、修改、刪除文件的實際內容; 表示能夠在目錄內新增、刪除、重命名文件
可執行(x) 表示能夠運行一個腳本程序。 表示能夠進入該目錄

文件權限的字符與數字表示:




3.文件的特殊權限

在復雜多變的生產環境中,單純設置文件的 rwx 權限無法滿足我們對安全和靈活性的需
求,因此便有了 SUID、 SGID 與 SBIT 的特殊權限位。

SUID

SUID 是一種對二進制程序進行設置的特殊權限,可以讓二進制程序的執行者臨時擁有屬主的權限(僅對擁有執行權限的二進制程序有效)。例如,所有用戶都可以執行 passwd 命令來修改自己的用戶密碼,而用戶密碼保存在/etc/shadow 文件中。

查看 passwd 命令屬性時發現所有者的權限由 rwx 變成了 rws,其中 x 改變成 s 就意味著該文件被賦予了 SUID 權限。另外有讀者會好奇,那么如果原本的權限是 rw-呢?如果原先權限位上沒有 x 執行權限,那么被賦予特殊權限后將變成大寫的 S。

[root@linuxprobe ~]# ls -l /etc/shadow
----------. 1 root root 1004 Jan 3 06:23 /etc/shadow
[root@linuxprobe ~]# ls -l /bin/passwd
-rwsr-xr-x. 1 root root 27832 Jan 29 2017 /bin/passwd

SGID

SGID 主要實現如下兩種功能:
? 讓執行者臨時擁有屬組的權限(對擁有執行權限的二進制程序進行設置)
? 在某個目錄中創建的文件自動繼承該目錄的用戶組(只可以對目錄進行設置)

舉例來說,在早期的 Linux 系統中,/dev/kmem 是一個字符設備文件,用于存儲內核程序要訪問的數據,權限為:

cr--r----- 1 root system 2, 1 Feb 11 2017 kmem

大家看出問題了嗎?除了 root 管理員或屬于 system 組成員外,所有用戶都沒有讀取該文件的權限。由于在平時我們需要查看系統的進程狀態,為了能夠獲取到進程的狀態信息,可在用于查看系統進程狀態的 ps 命令文件上增加 SGID 特殊權限位。查看 ps 命令文件的屬性信息:

-r-xr-sr-x 1 bin system 59346 Feb 11 2017 ps

這樣一來,由于 ps 命令被增加了 SGID 特殊權限位,所以當用戶執行該命令時,也就臨
時獲取到了 system 用戶組的權限,從而可以順利地讀取設備文件了。

SGID 的第二個功能,即某個目錄中創建的文件,將會與該目錄所屬的用戶組一致,這樣可以更便捷的賦予權限。

[root@linuxprobe ~]# cd /tmp
[root@linuxprobe tmp]# mkdir testdir
[root@linuxprobe tmp]# ls -ald testdir/
drwxr-xr-x. 2 root root 6 Feb 11 11:50 testdir/
[root@linuxprobe tmp]# chmod -Rf 777 testdir/
[root@linuxprobe tmp]# chmod -Rf g+s testdir/
[root@linuxprobe tmp]# ls -ald testdir/
drwxrwsrwx. 2 root root 6 Feb 11 11:50 testdir/

在testdir創建的文件會自動添加到root組當中

chmod 命令:用來設置文件或目錄的權限,格式為“chmod[參數] 權限 文件或目錄名稱”。

[root@linuxprobe ~]# chmod 760 test
[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 linuxprobe root 15 Feb 11 11:50 test

chown 命令:設置文件或目錄的所有者和所屬組,其格式為“chown [參數] 所有者:所屬組 文件或目錄名稱”。

[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 linuxprobe root 15 Feb 11 11:50 test
[root@linuxprobe ~]# chown root:bin test
[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 root bin 15 Feb 11 11:50 test

SBIT

現在,大學里的很多老師都要求學生將作業上傳到服務器的特定共享目錄中,但總是有幾個“破壞分子”喜歡刪除其他同學的作業,這時就要設置 SBIT(Sticky Bit)特殊權限位了(也可以稱之為特殊權限位之粘滯位)。 SBIT 特殊權限位可確保用戶只能刪除自己的文件,而不能刪除其他用戶的文件。換句話說,當對某個目錄設置了 SBIT 粘滯位權限后,那么該目錄中的文件就只能被其所有者執行刪除操作了

在linux中,/tmp目錄下的文件默認是帶有SBIT特殊權限位的,如果不是你創建的文件,你是無法刪除的,如下:

$ rm -rf test
rm: cannot remove ‘test’: Operation not permitted

如果要給文件賦予SBIT特殊權限位,使用以下指令:

chmod -R o+t linux/

4.文件的隱藏屬性

Linux 系統中的文件除了具備一般權限和特殊權限之外,還有一種隱藏權限,即被隱藏起
來的權限,默認情況下不能直接被用戶發覺。

chattr 命令

chattr 命令中用于隱藏權限的參數及其作用

參數 作用
i 無法對文件進行修改;若對目錄設置了該參數,則僅能修改其中的子文件內容而不能新建或刪除文件
a 僅允許補充(追加)內容,無法覆蓋/刪除內容(Append Only)
S 文件內容在變更后立即同步到硬盤(sync)
s 徹底從硬盤中刪除,不可恢復(用 0 填充原文件所在硬盤區域)
A 不再修改這個文件或目錄的最后訪問時間(atime)
b 不再修改文件或目錄的存取時間
D 檢查壓縮文件中的錯誤
d 使用 dump 命令備份時忽略本文件/目錄
c 默認將文件或目錄進行壓縮
u 當刪除該文件后依然保留其在硬盤中的數據,方便日后恢復
t 讓文件系統支持尾部合并(tail-merging)
X 可以直接訪問壓縮文件中的內容

一個簡單示例:

[root@linuxprobe ~]# echo "for Test" > linuxprobe
[root@linuxprobe ~]# chattr +a linuxprobe
[root@linuxprobe ~]# rm linuxprobe
rm: remove regular file ‘linuxprobe’? y
rm: cannot remove ‘linuxprobe’: Operation not permitted

lsattr 命令

一旦使用 lsattr 命令后,文件上被賦予的隱藏權限馬上就會原形畢露。此時可以按照顯示
的隱藏權限的類型(字母),使用 chattr 命令將其去掉:

[root@linuxprobe ~]# lsattr linuxprobe
-----a---------- linuxprobe
[root@linuxprobe ~]# chattr -a linuxprobe
[root@linuxprobe ~]# lsattr linuxprobe
---------------- linuxprobe
[root@linuxprobe ~]# rm linuxprobe
rm: remove regular file ‘linuxprobe’? y

文件訪問控制列表 ACL

如果希望對某個文件的權限進行更精細的分配,即本來只能給屬主或屬組賦予權限,這時候想要對屬主或屬組賦予rwx的權限,就需要用到文件的訪問控制列表(ACL)了。

setfacl 命令

setfacl 命令用于管理文件的 ACL 規則,格式為“setfacl [參數] 文件名稱”。

下面來設置用戶在/root 目錄上的權限:

[root@linuxprobe ~]# setfacl -Rm u:linuxprobe:rwx /root
[root@linuxprobe ~]# su - linuxprobe
Last login: Sat Mar 21 15:45:03 CST 2017 on pts/1
[linuxprobe@linuxprobe ~]$ cd /root
[linuxprobe@linuxprobe root]$ ls
anaconda-ks.cfg Downloads Pictures Public
[linuxprobe@linuxprobe root]$ cat anaconda-ks.cfg
[linuxprobe@linuxprobe root]$ exit

設置用戶ACL訪問控制的權限格式:setfacl -Rm u:用戶名:權限 文件,如下:

setfacl -Rm u:linuxprobe:rwx /root

設置用戶組ACL訪問控制的權限格式:setfacl -Rm g:組名:權限 文件,如下:

setfacl –Rm g:linuxprobe:rwx /root

如何知道某個文件是否賦予了ACL?

[root@linuxprobe ~]# ls -ld /root
dr-xrwx---+ 14 root root 4096 May 4 2017 /root

如果文件的權限的最后一個位變成了+號,代表文件被賦予了ACL;

getfacl 命令

getfacl 命令用于顯示文件上設置的 ACL 信息,格式為“getfacl 文件名稱”。


5.su 命令與 sudo 服務

sudo 命令用于給普通用戶提供額外的權限來完成原本 root 管理員才能完成的任務,格式
為“sudo [參數] 命令名稱”。

sudo 服務中的可用參數以及作用

參數 作用
-h 列出幫助信息
-l 列出當前用戶可執行的命令
-u 用戶名或 UID 值 以指定的用戶身份執行命令
-k 清空密碼的有效時間,下次執行 sudo 時需要再次進行密碼驗證
-b 在后臺執行指定的命令
-p 更改詢問密碼的提示語

visudo 命令

visudo 命令可用于配置用戶權限,配置 sudo 命令的配置文件時,其操作方法與 Vim 編輯器中用到的方法一致,因此在編寫完成后記得在末行模式下保存并退出。在 sudo 命令的配置文件中,按照下面的格式將第 99 行(大約)填寫上指定的信息。

誰可以使用 允許使用的主機 =(以誰的身份) 可執行命令的列表

六、存儲結構和磁盤劃分

1.幾個基本概念:

  • 主分區:相當于C盤,里面包含了啟動的引導文件,英文名叫做MBR
  • 拓展分區:主分區以外的分區
  • 邏輯分區:拓展分區下面的子分區,比如D盤、E盤、F盤,與拓展分區是包含的關系,他們的關系如下圖:


2.linux中目錄的結構

3.linux中常見的物理設備及名稱

4.掛載硬件設備

首先要知道一個問題,為什么我們可以隨意操作文件?

主要原因是這樣的,由于linux是一個很大的開源生態系統,所以它的文件系統有很多,不同的文件系統其讀寫方式肯定是不一樣的,常見的文件系統有這些:Ext3,Ext4,XFS...,見下圖:


這些文件系統的底層是硬件設備,文件系統是硬件設備的一套規范,但這些文件系統最后被VFS這個操作接口統一了,所以我們的用的cp,rm等指令都是這個VFS提供的。

那為什么又要掛載呢?

劉遄老師有一個最簡單、最貼切的解釋:當用戶需要使用硬盤設備或分區中的數據時,需要先將其與一個已存在的目錄文件進行關聯,而這個關聯動作就是“掛載”。

5.mount 命令

mount 命令用于掛載文件系統,格式為“mount 文件系統 掛載目錄”。

例如,要把設備/dev/sdb2 掛載到/backup 目錄,只需要在 mount 命令中填寫設備與掛載目錄
參數就行,系統會自動去判斷要掛載文件的類型,因此只需要執行下述命令即可:

[root@linuxprobe ~]# mount /dev/sdb2 /backup

雖然按照上面的方法執行 mount 命令后就能立即使用文件系統了,但系統在重啟后掛
載就會失效,也就是說我們需要每次開機后都手動掛載一下。

如果想讓硬件設備和目錄永久地進行自動關聯,就必須把掛載信息按照指定的填寫格式“設備文件 掛載目錄 格式類型 權限選項 是否備份 是否自檢”(各字段的意義見表 6-4)寫入到/etc/fstab 文件中。這個文件中包含著掛載所需的諸多信息項目,一旦配置好之后就能一勞永逸了。


[root@linuxprobe ~]# vim /etc/fstab
# #
/etc/fstab
# Created by anaconda on Wed May 4 19:26:23 2017
# #
Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rhel-root / xfs defaults 1 1
UUID=812b1f7c-8b5b-43da-8c06-b9999e0fe48b /boot xfs defaults 1 2
/dev/mapper /rhel-swap swap swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0
/dev/sdb2 /backup ext4 defaults 0 0

關注其中的:/dev/sdb2 /backup ext4 defaults 0 0,這是要添加的內容。

6.fdisk 命令

在 Linux 系統中,管理硬盤設備最常用的方法就當屬 fdisk 命令了。 fdisk 命令用于管理磁盤分區,格式為“fdisk [磁盤名稱]”,它提供了集添加、刪除、轉換分區等功能于一身的“一站式分區服務”。

7.du 命令

該命令用來查看一個或多個文件占用了多大的硬盤空間

[root@linuxprobe Desktop]# du -sh readit.txt 
4.0K    readit.txt

8.軟硬方式鏈接

假如a.txt鏈接到b.txt,且a.txt中有內容,則:

軟連接:b.txt是a.txt的快捷方式,打開b.txt 就是打開a.txt,刪除a.txt,b.txt將打不開,指令為ln -s a.txt b.txt
硬連接:是一種inode的引用,打開b.txt 就是打開a.txt,刪除a.txt,b.txt仍然能打開,且內容就是a.txt的內容,指令為ln a.txt b.txt

五、用戶和組

九、網絡

1、網卡配置

網卡 IP 地址配置的是否正確是兩臺服務器是否可以相互通信的前提。在 RHEL 5、 RHEL 6 中,網卡配置文件的前綴為 eth,第 1 塊網卡為eth0,第 2 塊網卡為 eth1;以此類推。而在 RHEL 7 中,網卡配置文件的前綴則以 ifcfg 開始,加上網卡名稱共同組成了網卡配置文件的名字,例如 ifcfg-eno16777736;好在除了文件名變化外也沒有其他大的區別。現在有一個名稱為 ifcfg-eno16777736 的網卡設備,我們將其配置為開機自啟動,并且 IP地址、子網、網關等信息由人工指定,其步驟應該如下所示。

第1步:首先切換到/etc/sysconfig/network-scripts 目錄中(存放著網卡的配置文件)。

第2步:使用 Vim 編輯器修改網卡文件 ifcfg-eno16777736,逐項寫入下面的配置參數并保存退出。由于每臺設備的硬件及架構是不一樣的,因此請讀者使用 ifconfig 命令自行確認各自網卡的默認名稱。
? 設備類型: TYPE=Ethernet
? 地址分配模式: BOOTPROTO=static
? 網卡名稱: NAME=eno16777736
? 是否啟動: ONBOOT=yes
? IP 地址: IPADDR=192.168.10.10
? 子網掩碼: NETMASK=255.255.255.0
? 網關地址: GATEWAY=192.168.10.1
? DNS 地址: DNS1=192.168.10.1

第3步:重啟網絡服務并測試網絡是否聯通。進入到網卡配置文件所在的目錄,然后編輯網卡配置文件,在其中填入下面的信息:

[root@linuxprobe ~]# cd /etc/sysconfig/network-scripts/
[root@linuxprobe network-scripts]# vim ifcfg-eno16777736
TYPE=Ethernet
BOOTPROTO=static
NAME=eno16777736
ONBOOT=yes
IPADDR=192.168.10.10
NETMASK=255.255.255.0
GATEWAY=192.168.10.1
DNS1=192.168.10.1

執行重啟網卡設備的命令(在正常情況下不會有提示信息),然后通過 ping 命令測試網絡能否聯通。由于在 Linux 系統中 ping 命令不會自動終止,因此需要手動按下 Ctrl-c 鍵來強行結束進程。

[root@linuxprobe network-scripts]# systemctl restart network
[root@linuxprobe network-scripts]# ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.081 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.083 ms
64 bytes from 192.168.10.10: icmp_seq=3 ttl=64 time=0.059 ms
64 bytes from 192.168.10.10: icmp_seq=4 ttl=64 time=0.097 ms
^C
--- 192.168.10.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.059/0.080/0.097/0.013 ms

2、網絡防火墻

相較于傳統的防火墻管理配置工具, firewalld 支持動態更新技術并加入了區域(zone)的概念。簡單來說,區域就是 firewalld 預先準備了幾套防火墻策略集合(策略模板),用戶可以根據生產場景的不同而選擇合適的策略集合,從而實現防火墻策略之間的快速切換。例如,我們有一臺筆記本電腦,每天都要在辦公室、咖啡廳和家里使用。按常理來講,這三者的安全性按照由高到低的順序來排列,應該是家庭、公司辦公室、咖啡廳。當前,我們希望為這臺筆記本電腦指定如下防火墻策略規則:在家中允許訪問所有服務;在辦公室內僅允許訪問文件共享服務;在咖啡廳僅允許上網瀏覽。在以往,我們需要頻繁地手動設置防火墻策略規則,而現在只需要預設好區域集合,然后只需輕點鼠標就可以自動切換了,從而極大地提升了防火墻策略的應用效率。 firewalld 中常見的區域名稱(默認為 public)以及相應的策略規則如表所示。

區域 默認策略規則
trusted 允許所有的數據包
home 拒絕流入的流量,除非與流出的流量相關;而如果流量與 ssh、 mdns、 ipp-client、amba-client 與 dhcpv6-client 服務相關,則允許流量《Linux 就該這么學》
internal 等同于 home 區域
work 拒絕流入的流量,除非與流出的流量數相關;而如果流量與 ssh、 ipp-client 與
dhcpv6-client 服務相關,則允許流量
public 拒絕流入的流量,除非與流出的流量相關;而如果流量與 ssh、 dhcpv6-client 服務相關,則允許流量
external 拒絕流入的流量,除非與流出的流量相關;而如果流量與 ssh 服務相關,則允許流量
dmz 拒絕流入的流量,除非與流出的流量相關;而如果流量與 ssh 服務相關,則允許流量
block 拒絕流入的流量,除非與流出的流量相關
drop 拒絕流入的流量,除非與流出的流量相關
2.1終端管理工具

firewallcmd 是 firewalld 防火墻配置管理工具的 CLI(命令行界面)版本。它的參數一般都是以“長格式”來提供的,可以用 Tab 鍵來補齊。

查看 firewalld 服務當前所使用的區域:

[root@linuxprobe ~]# firewall-cmd --get-default-zone
public

查詢 eno16777728 網卡在 firewalld 服務中的區域:

[root@linuxprobe ~]# firewall-cmd --get-zone-of-interface=eno16777728
public

把 firewalld 服務中 eno16777728 網卡的默認區域修改為 external,并在系統重啟后生效。分別查看當前與永久模式下的區域名稱:

[root@linuxprobe ~]# firewall-cmd --permanent --zone=external --change-interface=
eno16777728
success
[root@linuxprobe ~]# firewall-cmd --get-zone-of-interface=eno16777728
public
[root@linuxprobe ~]# firewall-cmd --permanent --get-zone-of-interface=eno16777728
external

把 firewalld 服務的當前默認區域設置為 public:

[root@linuxprobe ~]# firewall-cmd --set-default-zone=public
success
[root@linuxprobe ~]# firewall-cmd --get-default-zone
public

啟動/關閉 firewalld 防火墻服務的應急狀況模式,阻斷一切網絡連接(當遠程控制服務器
時請慎用):

[root@linuxprobe ~]# firewall-cmd --panic-on
success
[root@linuxprobe ~]# firewall-cmd --panic-off
success

查詢 public 區域是否允許請求 SSH 和 HTTPS 協議的流量:

[root@linuxprobe ~]# firewall-cmd --zone=public --query-service=ssh
yes
[root@linuxprobe ~]# firewall-cmd --zone=public --query-service=https
no

把 firewalld 服務中請求 HTTPS 協議的流量設置為永久允許,并立即生效:

[root@linuxprobe ~]# firewall-cmd --zone=public --add-service=https
185
success
[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-service=https
success
[root@linuxprobe ~]# firewall-cmd --reload
success

把 firewalld 服務中請求 HTTP 協議的流量設置為永久拒絕,并立即生效:

[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --remove-service=http
success
[root@linuxprobe ~]# firewall-cmd --reload
success

把在 firewalld 服務中訪問 8080 和 8081 端口的流量策略設置為允許,但僅限當前生效:

[root@linuxprobe ~]# firewall-cmd --zone=public --add-port=8080-8081/tcp
success
[root@linuxprobe ~]# firewall-cmd --zone=public --list-ports
8080-8081/tcp

把原本訪問本機 888 端口的流量轉發到 22 端口,要且求當前和長期均有效:

注:流量轉發命令格式:firewall-cmd --permanent --zone=< > --add-forward-port=port=< >:proto=< >:toport=< >:toaddr=< IP >

[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-forward-port=
port=888:proto=tcp:toport=22:toaddr=192.168.10.10
success
[root@linuxprobe ~]# firewall-cmd --reload
success

在客戶端使用 ssh 命令嘗試訪問 192.168.10.10 主機的 888 端口:

[root@client A ~]# ssh -p 888 192.168.10.10
The authenticity of host '[192.168.10.10]:888 ([192.168.10.10]:888)' can't
be established.
ECDSA key fingerprint is b8:25:88:89:5c:05:b6:dd:ef:76:63:ff:1a:54:02:1a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[192.168.10.10]:888' (ECDSA) to the list of known hosts.
root@192.168.10.10's password: root
Last login: Sun Jul 19 21:43:48 2017 from 192.168.10.10

firewalld 中的富規則表示更細致、更詳細的防火墻策略配置,它可以針對系統服務、端口號、源地址和目標地址等諸多信息進行更有針對性的策略配置。它的優先級在所有的防火墻策略中也是最高的。比如,我們可以在 firewalld 服務中配置一條富規則,使其拒絕192.168.10.0/24 網段的所有用戶訪問本機的 ssh 服務(22 端口):

[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-rich-rule="
rule family="ipv4" source address="192.168.10.0/24" service name="ssh" reject"
success
[root@linuxprobe ~]# firewall-cmd --reload
success

在客戶端使用 ssh 命令嘗試訪問 192.168.10.10 主機的 ssh 服務(22 端口):

[root@client A ~]# ssh 192.168.10.10
Connecting to 192.168.10.10:22...
Could not connect to '192.168.10.10' (port 22): Connection failed.
2.2 圖形管理工具

如何打開圖形管理工具:

圖形界面如下:

  • 1:Configuration,選擇運行時(Runtime)模式或永久(Permanent)模式的配置。
  • 2:Zones,可選的策略集合區域列表。
  • 3:Services,常用的系統服務列表。
  • 4:public,當前正在使用的區域。
  • 5:Services,管理當前被選中區域中的服務。
  • 6:Ports,管理當前被選中區域中的端口。
  • 7:Masquerading,開啟或關閉 SNAT(源地址轉換協議)技術。
  • 8:Port Forwarding,設置端口轉發策略。
  • 9:ICMP Filter,控制請求 icmp 服務的流量。
  • 10:Rich Rules,管理防火墻的富規則。
  • 11:interfaces,管理網卡設備。
  • 12:被選中區域的服務,若勾選了相應服務前面的復選框,則表示允許與之相關
    的流量。
  • 13: firewall-config 工具的運行狀態。
2.3 服務的訪問控制列表

TCP Wrappers 是 RHEL 7 系統中默認啟用的一款流量監控程序,它能夠根據來訪主機的地址
與本機的目標服務程序作出允許或拒絕的操作。

TCP Wrappers 服務的防火墻策略由兩個控制列表文件所控制,/etc/hosts.deny和/etc/hosts.allow,系統將會先檢查允許控制列表文件(/etc/hosts.allow),如果匹配到相應的允許策略則放行流量; 如果沒有匹配,則去進一步匹配拒絕控制列表文件(/etc/hosts.deny),若找到匹配項則拒絕該流量。如果這兩個文件全都沒有匹配到,則默認放行流量。


建議先編寫拒絕策略規則,再編寫允許策略規則,以便直觀地看到相應的效果。

[root@linuxprobe ~]# vim /etc/hosts.deny
# #
hosts.deny This file contains access rules which are used to
# deny connections to network services that either use
# the tcp_wrappers library or that have been
# started through a tcp_wrappers-enabled xinetd.
# #
The rules in this file can also be set up in
# /etc/hosts.allow with a 'deny' option instead.
# #
See 'man 5 hosts_options' and 'man 5 hosts_access'
# for information on rule syntax.
# See 'man tcpd' for information on tcp_wrappers
sshd:*
[root@linuxprobe ~]# ssh 192.168.10.10
ssh_exchange_identification: read: Connection reset by peer

接下來,在允許策略規則文件中添加一條規則,使其放行源自 192.168.10.0/24 網段,訪問本機 sshd 服務的所有流量。可以看到,服務器立刻就放行了訪問 sshd 服務的流量,效果非常直觀:

[root@linuxprobe ~]# vim /etc/hosts.allow
# #
hosts.allow This file contains access rules which are used to
# allow or deny connections to network services that
# either use the tcp_wrappers library or that have been
# started through a tcp_wrappers-enabled xinetd.
# #
See 'man 5 hosts_options' and 'man 5 hosts_access'
# for information on rule syntax.
# See 'man tcpd' for information on tcp_wrappers
sshd:192.168.10.
[root@linuxprobe ~]# ssh 192.168.10.10
The authenticity of host '192.168.10.10 (192.168.10.10)' can't be established.
ECDSA key fingerprint is 70:3b:5d:37:96:7b:2e:a5:28:0d:7e:dc:47:6a:fe:5c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.10' (ECDSA) to the list of known hosts.
root@192.168.10.10's password:
Last login: Wed May 4 07:56:29 2017
[root@linuxprobe ~]#
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容