阮一峰Bash腳本教程學(xué)習(xí)筆記

教程地址

快捷鍵:

ctrl+L: 清除屏幕并移到頂部
ctrl+U: 刪到行首(剪) ctrl+A: 移到行首
ctrl+K: 刪到行尾(剪) ctrl+E: 移到行尾
ctrl+b, f, (左移, 右移)
alt+b,f (前, 后移一個單詞)
ctrl+1 等同于clear
ctrl+d delete, ctrl+w 刪到單詞首
alt+t 詞換位, ctrl+t 字符換位 (與前一個)
alt+d, alt+backspace 剪切至詞首, 詞尾
ctrl+y 粘貼
$ ’Something wrong happend’ >&2

解釋:

>代表重定向輸出
&表示接下來的是一個文件描述符數(shù)字(file descriptor number)
2表示stderr
所以就是把上述字符串輸出到stderr里去的意思,
如果是$ ”str” <2 (沒有&), 則會輸出到一個叫2的文件里去

echo

-n: 可以取消結(jié)尾的換行
-e: 解釋字符串里的轉(zhuǎn)義符

擴展(通配符)

$ ~/walker # 表示用戶目錄下的walker目錄
$ ~walker # 表示名為walker的目錄
$ ~+ # 擴展為當前目錄, 等同于 pwd
$ echo d{a, e, I, o, u}g 輸出: dag, deg, dig, dog, dug # 大括號內(nèi)不要有空格(否則會當成參數(shù))
$ echo {j{p,pe}g, png} —> 嵌套

波浪線, 方括號的括號都是基于”路徑”的, 如果當前路徑?jīng)]有匹配到對應(yīng)的文件名, 則會變成字符串原樣輸出, 而大括號則不然, 是基于”邏輯”的, 只管擴展, 不會去探測擴展后對應(yīng)的路徑存不存在, 因此可能報錯文件不存在.
echo [a,b].txt, 如果不存在a.txt, b.txt, 則會變成”[a,b].txt”這樣一個輸出, 而{a,b}.txt一定會擴展成a.txt, b.txt
例外:
在用..來擴展時, 如果系統(tǒng)無法理解, 則不會擴展, 如{1..5}會擴展成1,2,3,4,5, 但{ab..123}, 則會變成字符串
但是前導(dǎo)0不參與路徑匹配: {01…5} # 01,02,03,04,05 (幾個零都可以)
步長:{0..8..2} (未測試成功) # 要打開哪個shopt開關(guān)?
活用:

$ echo .{mp{3..4},m4{a,b,p,v}} # 匹配了: .mp3 .mp4 .m4a .m4b .m4p .m4v
$ mkdir {2007..2009}-{01..12}  # 建了2007-2009每年12個目錄
for I in {1..4}

注意驚嘆號的使用(類似正則里的^)

$ echo ${!S*} # 返回所有以S開頭的”變量名”, 如SHELL, SSH..等

另兩種轉(zhuǎn)義(string interpolation):

$ echo date is $(date) # 即包在$(…)中
$ echo date is `date` # 包在反引號中

但是要計算2+2, 只有echo $((2+2)) 這種形式, 反引號就不行了

[[:alnum:]], [[:digit:]]等預(yù)置的字符類擴展見: https://wangdoc.com/bash/expansion.html 很豐富, 建議詳讀.

(?, \*, +, @, !)則為匹配的個數(shù), 分別是(0或1, 0或多, 一或多, 一個, 非一個), 如song@(.)mp3等同于song.mp3,
是的, 不同于正則, 它是先規(guī)定個數(shù), 再設(shè)定匹配字串

注: 需要打開shopt -s extglob

雙引號碰到$, 反引號和反斜杠都會自動擴展, 所以echo “$SHELL” 等同于echo echo \$SHELL
雙引號能保留”輸出”的格式, 比如 echo `cal`, 格式就沒了, 自己試試看? 而echo “$(cal)”則可以保留格式:

$ echo "$(cal)"
      六月 2020
日 一 二 三 四 五 六
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

大段文字輸入可以用

$command << token
your long inputs
token

等同于: echo "your long inputs" | command 即把echo的輸出作為command的輸入, 這個一般用于多行文本

texts里面可以進行使用變量, 但是如果把token用雙引號包起來就不能解釋變量了.

如果只是簡單字符串, 用下面更明確:
$ command <<< ‘text’
如: $ cat <<< “hello world”, 一樣等同于 $ echo “hello world” | cat
<<< 還有一個作用就是把變量值用這種方式能變成標準輸入, 這樣被”計算”出來的值也能用于只接受標準輸入的命令了, 比如read

變量

printenv PATHecho $PATH等同
解釋變量中的變量, 比如$PATH, 不是想象中的$嵌套: ${${myvar}}, 應(yīng)該這么用

$ myvar=PATH
$ echo ${!myvar}, # 即多加一個驚嘆號

$?: 上一個命令的退出碼(0成功, 1失敗)
$$: 當前Shell進程的ID
$_: 上一個命令的最后一個參數(shù)
$!: 最后一個后臺執(zhí)行的異步命令的進程ID
$0: 當前Shell的名稱
$-: 當前shell的啟動參數(shù), $@, $# 表示腳本的參數(shù)數(shù)量

$?命令除了取出上一個命令的返回值, 也可以取出上一個函數(shù)的返回值

${varname-:value} 取值, 如果不存在則返value, 但不賦值
${varname=:value} 取值, 如果不存在則返value, 順便賦值
${varname+:value} 如果有值則返value(而不是值本身), 沒有值則為空, 所以這個時候的value一般用一個標識符號就好了
${varname?:value} 取值, 如果不存在就報錯并把value作為錯誤錯誤打印出來
比如 $ filename=${$1:?”filename missing”} 從腳本中取第一個參數(shù)作為文件名, 發(fā)現(xiàn)沒有文件名就報錯退出

變量都是字符串, 可以用declare來進行一些限定

$ declare -I v1=13 v2=14 v3=v1+v2 # 聲明為integer
$ echo $v3
# 這樣更快: 
$ let v=13+14  # 如果習(xí)慣了=兩邊加空格, 則包到引號里: $ let “v = 13 + 14”

字符串

${#”string”} 長度
${varname:offset:length} 切片(變量名不需要美元符號)
刪除: (# 和 ## 的區(qū)別就是貪婪與否的區(qū)別)

$ phone="555-456-1414"
$ echo ${phone#*-}
> 456-1414
$ echo ${phone##*-}
> 1414

替換: ${variable/#pattern/string} 注意, # 左邊多了一個 / , 右邊多了替換字串
以上, 都是從頭匹配, 從尾部匹配把 # 換成 %
任意位置匹配則換成/, 所以就成了你們最熟悉的語法:varname/search/replace

這個時候再回頭看/# , /%, 不過是/語法的修飾符罷了(限定起始方向)

${varname^^}, ${varname,,} # 轉(zhuǎn)大寫, 轉(zhuǎn)小寫

數(shù)值運算

逗號是求值, 如
$ echo $((foo = 1+2, 3*4)) 輸出為12, 但foo的值是3, 依次計算, 輸出是逗號后面的

expr命令等同于雙括號: expr 3+5$((3+5))同義

行操作

Bash內(nèi)置Readline庫, 默認采用Emacs快捷鍵, 切換:

$ set -o vi 或 $ set -o emacs

切換目錄/堆棧

不管你cd到哪個了哪個目錄, 想回到cd前的目錄, 用cd -就行了
pushd , popd則可以把目錄推到堆棧里, 演示:

$ pushd 2
/test/1/2 /test/1
$ pushd 3
/test/1/2/3 /test/1/2 /test/1
$ pushd 4
/test/1/2/3/4 /test/1/2/3 /test/1/2 /test/1
$ dirs  # 其實每一次pushd都會把當前堆棧dirs出來
/test/1/2/3/4 /test/1/2/3 /test/1/2 /test/1
$ cd /tmp
$ dirs # 觀察, cd其實只是把頂層給改了, 不會增減層級
/tmp /test/1/2/3 /test/1/2 /test/1
$ cd /usr
$ dirs  # 驗算
/usr /test/1/2/3 /test/1/2 /test/1

現(xiàn)在你知道 了, cd永遠只是更改頂棧, 大多數(shù)情況下, 你可以用pushd來替換cd, 這樣你就有了后退權(quán)
此時你再popd, 目錄會順利切到/test/1/2/3, 不管你進行過多少次cd, 第二層都不會變并且能直接pop出來
小練習(xí)
如果你查看堆棧, 要從第4個開始后退(0為起始), 那么可以把從3開始(不是4)的記錄提到頂層來(然后再popd):
$ pushd +3 (加號不可省)

注意, 此時0, 1, 2都還在, 只是挪到了尾巴

popd +3則不是”移動”, 而是刪除了, 意思是正向刪除3個, 如果不帶+, 則理解為刪除3以后的所有堆棧(即從4開始)

注意: 為什么要從第4個開始退要把從3開始的移到頂層呢?
因為如下dirs: /1, /2, /3 , 你做popd, 是會回到/2的
可見頂棧永遠表示的是"當前"目錄. 所以你自然無法跳到當前目錄.
pushd, popd+數(shù)字改動的只是堆棧表, 不是目錄, 即雖然你的目錄沒變, 但是系統(tǒng)認為你在第三層, 這個時候再后退(popd)自然到了目錄表里的下一層/4.

腳本

shebang行#!/usr/bin/env bash 的寫法是為了避免#!/bin/bash 這種寫法時bash不在bin目錄
source命令可以 用一個點來表示: . ~/.bash_profile
讀用戶的輸入:

$ read firstname lastname
$ “you input: $firstname, $lastname” # 如果read后沒有給變量名, 則由默認的$REPLY來取出

讀文件:

while read myline  # 每次讀一行
do
  echo "$myline"
done < $filename  # 注意這里特殊的傳參方式, 同時, 如果不傳入文件路徑, 就是一個無限循環(huán)了(read)

存數(shù)組:

$ read -a varname. #  -a 參數(shù)把用戶的多個輸入全存到`varname`這個數(shù)組里了

其它有用的:

# -e 參數(shù)使得用戶在輸入的時候能用tab補全(包含所有readline庫快捷鍵),
# 如果沒有這個參數(shù)輸入文本的時候是不能使用快捷鍵的
$ read -e -p “please input the path to the file” 
# -s 可以隱藏用戶的輸入, 通常用于密碼
$ read -s  -p “input password”
# -p 顯然就是能直接顯示輸入前的提示了

條件判斷

if里面的test命令
test expression, [ expression], [[ expression ]] 是等價的(第三種支持正則) 空格不能省
[ -? file ] 查看文件狀態(tài)有非常多的表達式(參數(shù)), 具體參閱https://wangdoc.com/bash/condition.html 推薦閱讀
for循環(huán)
for [ test ] in list; do … done 其中的in list如果省略, 則代表所有腳本參數(shù)”$@“:

$ for filename; do echo “$filename”; done
# 等同于
$ for filename in “$@“; do echo “$filename”; done

同理, 如果是用在函數(shù)中, 則等于所有函數(shù)參數(shù).
用雙括號, 變量也無需加$
for (( i=0; i<5; i+=1 )); do echo $i; done
case in, 如果希望一個匹配后繼續(xù)做下一個匹配(passthrough), 每一個case 的結(jié)尾用;;&而不是;; (多了一個&)

select

select生成的菜單, 選擇并執(zhí)行命令后, 要自行在do-done體內(nèi)用break退出, 否則會一直要你選擇

數(shù)組

以下方式聲明數(shù)組

$ names=(hatter [5]=duchess Alice), 指定了0, 5, 6, 其它為空字符串
$ mp3s=( *.mp3 )
$ declare -a ARRAYNAME
$ read -a ARRAYNAME

讀取的時候: $ echo ${array[1]} 大括號不可省
@仍然是返回所有元素: $ echo ${array[@]} 但是在for…in中, 要把整個表達式放雙引號中:

$ activities=( swimming "water skiing" canoeing "white-water rafting" surfing )
$ for act in “${activities[@]}”; do….; done

不然其中有”water”, “skiing”,”white-water", rafting”等都會被拆開(bug吧? 字符串也拆)
@換成*, 加上雙引號, 則會一個個字符返回
拷貝數(shù)組最方便的方法:

$ hobbies=( “${activities[@]}” diving ) # 順便演示了為數(shù)組添加成員

直接賦值給一個數(shù)組(即沒有指定索引), 則是賦給第0個組員, 同理, 使用數(shù)組名也是使用的0號組員

# 以下@可以換成*
$ echo ${#array[@]} # #仍然用以計數(shù), 但是如果傳的是具體索引, 則返回的是對應(yīng)項的字符串長度
$ echo ${!array[@]} 用以返回有值的索引 (為空的不返回) # 活用的話遍歷數(shù)組更高效
$ echo ${array[@]:2:3} # 切片
$ arr+=(3 4 5) # 追加
$ unset arr[2] # 刪除 , 或: 
$ arr[2]= # 或
$ arr[2]=‘’
# 以上三者等效, 

根據(jù)上面知識$ arr= 表示刪除第一個成員, 但是unset arr 則是清空整個數(shù)組了
也可以用字符串做索引, 就成了字典了:

$ declare -A colors  # 變成大寫即可
$ colors[“red”]=“#ff0000”

set命令

單獨一個set會顯示所有環(huán)境變量和Shell函數(shù)
以下都可以以set -xxx 的方式寫在腳本頭任何位置, 就當一個即時開關(guān)使用吧
也可以在調(diào)用bash腳本前傳入比如: bash -eux script.sh
-u: 遇到不存在的變量就報錯, 而不是忽略 與 -o nounset 等價
-x: 每一個命令執(zhí)行前會先打印出來 等同于 -o xtrace, 關(guān)閉用set +x (組合起來用就是一個小環(huán)境)
-e: 有錯誤就中止 等同于 -o errexit
-o pipefail: 即使在管道中, 有錯也中止(-e 在管道中會失效)
-n: -o noexec 不執(zhí)行命令只檢查語法
-f: -o noglob 不對通配符進行文件名(路徑)擴展 可用+f 關(guān)閉
-v: -o verbose 打印shell接收到的每一行輸入 可用+v 關(guān)閉
$ set -euxo pipefail 一般這么四個連用

shopt

即: shell option
同set, 直接shopt也可以列出所有參數(shù), -s, -u分別是是打開, 關(guān)閉某個參數(shù)
shopt 參數(shù)名, 可直接查詢該參數(shù)是否打開關(guān)閉, 但是如果是用于編程, 因為返回是字符串不好判斷, 所以提供了-q參數(shù)(返回0/1, 分別表示打開/關(guān)閉)

$ if shopt -q globstar; then …; fi

除錯

# 先看目錄存不存在, 然后再進入, 然后再打印出來將要刪除的文件, 
# 這是最安全的刪除方法
# 否則一旦目錄不存在, 不同的寫法會有不同的問題
[[ -d $dir_name ]] && cd $dir_name && echo rm *  

如果在執(zhí)行bash腳本前加入-x參數(shù), 則每一條命令執(zhí)行前都會打印出來 # 等同于set -x

或者寫在腳本的shebang行里也行

每一條命令會同上一個標識符作前綴, 默認是+, 可以用export PS4=‘$LINENO +’這種方式自定義(比如現(xiàn)在就加上了行號)
幾個環(huán)境變量
$LINENO: 這個變量在哪, 打印的就是這一行的行號
$FUNCNAME: 返回一個數(shù)組, 函數(shù)調(diào)用的名稱堆棧, 最里層(即本函數(shù))的是0
$BASH_SOURCE: 返回一個數(shù)組, 函數(shù)調(diào)用的腳本堆棧, 即每層調(diào)用的腳本是哪一個, 最里層(即本文件)的是0
$BASH_LINENO: 返回一個數(shù)組, 函數(shù)每一次被調(diào)用時在該腳本的行號, 同樣也是從最里層開始
例:

${BASH_SOURCE[1] = main.sh  # [0] 是文件本身, 所以要[1]
${BASH_LINENO[0] = 17  # 調(diào)用來源的行號  —> 所以調(diào)用來源的行號的索引永遠比調(diào)用來源(文件)的索引要小1
${FUNCNAME[0]} = hello  # 本方法(或者說”被調(diào)用的方法”)

上例代表在 main.sh的17行調(diào)用了hello()方法
小練習(xí)

#!/bin/bash
source lv2.sh   # 引入外部腳本
function lv1method()
{
    echo ---------lv1------------
    i=0
    for v in "${BASH_LINENO[@]}"; do
        echo "bash_line_no[$((i++))]: $v"
    done
    i=0
    for v in "${FUNCNAME[@]}"; do
        echo "func_name[$((i++))]: $v"
    done
    i=0
    for v in "${BASH_SOURCE[@]}"; do
        echo "bash_source[$((i++))]: $v"
    done
    lv2method # 調(diào)用外部腳本的方法
}

以上腳本, 多做幾次嵌套, 打印出來看看索引之間的關(guān)系
輸出:

---------lv1------------
bash_line_no[0]: 5
bash_line_no[1]: 0
func_name[0]: lv1method
func_name[1]: main
bash_source[0]: lv1.sh
bash_source[1]: entry.sh
---------lv2------------
bash_line_no[0]: 21
bash_line_no[1]: 5
bash_line_no[2]: 0
func_name[0]: lv2method
func_name[1]: lv1method
func_name[2]: main
bash_source[0]: lv2.sh
bash_source[1]: lv1.sh
bash_source[2]: entry.sh
---------lv3------------
bash_line_no[0]: 19
bash_line_no[1]: 21
bash_line_no[2]: 5
bash_line_no[3]: 0
func_name[0]: lv3method
func_name[1]: lv2method
func_name[2]: lv1method
func_name[3]: main
bash_source[0]: lv3.sh
bash_source[1]: lv2.sh
bash_source[2]: lv1.sh
bash_source[3]: entry.sh

臨時文件

安全的用法:

trap 'rm -f "$TMPFILE"’ EXIT  # 退出時刪除臨時文件)
TMPFILE=$(mktemp) || exit 1  # 用mktemp命令建立臨時文件可以只有本人能讀, 如果失敗就退出
echo "Our temp file is $TMPFILE”

參數(shù):
-d: 創(chuàng)建的是目錄
-p: 指定目錄
-t: 指定模板
mktemp -t aaa.XXXXXXX 能生成/tmp/aaa.yZ1HgZV(與X個數(shù)相同)
trap是用來響應(yīng)系統(tǒng)信號的, 如ctrl+c產(chǎn)生中斷信號SIGINT
$ trap -l 列出所有信號(自己打印出來看看)
trap的格式: $ trap [動作] [信號1] [信號2] ...
trap 命令接的信號有如下

  • HUP:編號1,腳本與所在的終端脫離聯(lián)系昵观。
  • INT:編號2,用戶按下 Ctrl + C,意圖讓腳本中止運行。
  • QUIT:編號3征冷,用戶按下 Ctrl + 斜杠抛丽,意圖退出腳本样漆。
  • KILL:編號9,該信號用于殺死進程蛹稍。
  • TERM:編號15吧黄,這是kill命令發(fā)出的默認信號。
  • EXIT:編號0唆姐,這不是系統(tǒng)信號拗慨,而是 Bash 腳本特有的信號,不管什么情況,只要退出腳本就會產(chǎn)生赵抢。

如果trap要執(zhí)行多條命令, 可以封裝到函數(shù)里, 命令的位置寫函數(shù):$ trap func_name EXIT

啟動環(huán)境

登錄session依次啟動如下腳本:

  • /etc/profile
  • /etc/profile.d # 目錄下的所有.sh文件
  • ~/.bash_profile # 如果有, 則中止
  • ~/.bash_login # 如果有, 則中止 此為C shell 初始化腳本
  • ~/.profile # Bourne shell 和 Korn shell 初始化腳本

通過$ bash - -login 參數(shù), 可以強制執(zhí)行以上腳本
非登錄session

  • /etc/bash.bashrc # 所有用戶都執(zhí)行
  • ~/.bashrc # 當前用戶的

啟動參數(shù):
-n: 不執(zhí)行腳本, 只檢查語法
-v: 執(zhí)行語句前先輸出
-x: 執(zhí)行語句后輸出該語句

~/.bash_logout 退出時要執(zhí)行的命令
$ include /etc/inputrc~/.inputrc里加這一行, 可以在里面自定義快捷鍵

命令提示符

上面提到過$PS4能修改set -x時打印的每句語句前面的+
命令提示符默認的$符號(根用戶#號)則可以用$PS1來修改, 怎么改參考https://wangdoc.com/bash/prompt.html
$PS2表示的是輸入時折行的提示符, 默認為>
$PS3表示使用select命令時系統(tǒng)輸入菜單的提示符

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末剧蹂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子烦却,更是在濱河造成了極大的恐慌宠叼,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件其爵,死亡現(xiàn)場離奇詭異冒冬,居然都是意外死亡,警方通過查閱死者的電腦和手機摩渺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門简烤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摇幻,你說我怎么就攤上這事横侦。” “怎么了绰姻?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵枉侧,是天一觀的道長。 經(jīng)常有香客問我狂芋,道長榨馁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任银酗,我火速辦了婚禮辆影,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘黍特。我一直安慰自己蛙讥,他們只是感情好,可當我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布灭衷。 她就那樣靜靜地躺著次慢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪翔曲。 梳的紋絲不亂的頭發(fā)上迫像,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天,我揣著相機與錄音瞳遍,去河邊找鬼闻妓。 笑死,一個胖子當著我的面吹牛掠械,可吹牛的內(nèi)容都是我干的由缆。 我是一名探鬼主播注祖,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼均唉!你這毒婦竟也來了是晨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤舔箭,失蹤者是張志新(化名)和其女友劉穎罩缴,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體层扶,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡箫章,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了镜会。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炉抒。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖稚叹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拿诸,我是刑警寧澤扒袖,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站亩码,受9級特大地震影響季率,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜描沟,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一飒泻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吏廉,春花似錦泞遗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至佩伤,卻和暖如春聊倔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背生巡。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工耙蔑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人孤荣。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓甸陌,卻偏偏與公主長得像须揣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子邀层,可洞房花燭夜當晚...
    茶點故事閱讀 43,492評論 2 348