|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 thinkfunny 于 2019-12-9 13:34 编辑 ! g: e8 J2 `2 q* t2 x b
- \8 a$ H- \+ Y7 c# Z8 o3 }* G
4 _1 O: }/ D) v& i
文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识。
; t) O* [. K+ V, `. p( O y+ Q( }( |# P
本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录、挂载基本原理、文件存储结构、软链接硬链接、和常见目录的介绍。相信有了这些知识对于深入的学习linux会有一定的帮助。文章例子主要是基于ubuntu发行版。8 p+ s9 G) H# L/ d0 Q5 |
1 {+ Z3 k# T; x$ N2 H5 g
如有不对之处请大家多多指出。' p+ s- H& f; k) D8 l' S/ b4 ?
7 g8 i( Q$ X$ |* L) D* j1 a
1.Linux磁盘分区和目录" t& y" B4 T3 Z; s
; \. e0 ]' E$ y( R, a; j
Linux发行版本之间的差别很少,差别主要表现在系统管理的特色工具以及软件包管理方式的不同。目录结构基本上都是一样的。Windows的文件结构是多个并列的树状结构,最顶部的是不同的磁盘(分区),如:C,D,E,F等。
{* z5 j1 q8 D; r7 V! c( q
7 R8 @! N! y. W% wLinux的文件结构是单个的树状结构.可以用tree进行展示。 在Ubuntu下安装tree(sudo apt-get install tree),并可通过命令来查看。* L2 e$ A& z7 m& b
. K3 z. C9 W D9 C" f每次安装系统的时候我们都会进行分区,Linux下磁盘分区和目录的关系如下:) E8 s+ z; f" s# ?& o
3 S% G2 ^) o; p; c d; m– 任何一个分区都必须挂载到某个目录上。
4 T9 t; r' Z3 K; `% m
8 ^4 g" v- a7 \– 目录是逻辑上的区分。分区是物理上的区分。! X, R% c6 O+ G. T: P
8 ?5 F8 H4 ~9 f/ j- Q& O& _$ ^– 磁盘Linux分区都必须挂载到目录树中的某个具体的目录上才能进行读写操作。2 P1 f3 D8 ]( m, T3 Q! s
& L/ z6 w- z5 [: B1 i– 根目录是所有Linux的文件和目录所在的地方,需要挂载上一个磁盘分区。 j: v1 q6 S) M) P e2 C
2 S6 H+ e( Z' |
以下是我们可能存在的一种目录和分区关系:: s0 k1 [ K' B* y* k+ }
1 K% _' L+ @$ |9 d7 a# x1 Y
; k0 C4 @3 ~! |6 K7 `* z+ u! w) [# y
4 ~) {% }6 i7 s0 f
图1:目录和分区关系
Q7 C/ d0 }* T( v' A/ W4 @; s1 t$ ]" b D' k) U; O5 _
Q:如何查看分区和目录及使用情况?" ?9 I6 {( H) C) o& I
, @2 g8 [) P# }2 [# |9 G h– fdisk查看硬盘分区表5 {4 d5 J1 c$ i/ Q! F5 k
N+ a+ ~5 j3 r4 }% g8 ~9 ^
– df:查看分区使用情况
) n& e9 R- m& ?7 W; S" o' a9 t# B6 t0 U) c) [
– du: 查看文件占用空间情况
# l1 u; T Z3 f) P/ y, ?+ q* G# e7 i
Q: 为什么要分区,如何分区?# z. l) c! o! B+ S4 u
- l2 }/ i+ l% O/ }% N7 q1 U– 可以把不同资料,分别放入不同分区中管理,降低风险。
' }6 E5 a7 m3 K z% F+ h: O) ^: I* c, X4 `
– 大硬盘搜索范围大,效率低
. }: k. }: o7 y. F: ^+ d/ f
0 m* {7 u& D' C; P8 k- a– 磁盘配合只能对分区做设定9 n9 `0 i! B7 k& R H9 o) Z
+ s# B) y9 u7 u5 Z4 t
– /home /var /usr/local经常是单独分区,因为经常会操作,容易产生碎片7 v# `- Q0 s) z
, @! w8 }9 g S. b
: g; y8 H2 a# H. F8 E
/ f; X' }5 g) O! c* G; m. g2.Mount挂载和NFS简介
, [- r3 b/ Q3 W) [5 T+ b% T0 N2 r. S# C6 |+ ^- `5 | H
挂载的概念 :当要使用某个设备时,例如要读取硬盘中的一个格式化好的分区、光盘或软件等设备时,必须先把这些设备对应到某个目录上,而这个目录就称为“挂载点(mount point)”,这样才可以读取这些设备,而这些对应的动作就是“挂载”。 将物理分区细节屏蔽掉。用户只有统一的逻辑概念。所有的东西都是文件。Mount命令可以实现挂载:$ W4 }0 K/ N) B2 {4 ^& j
; O q. [# R# o7 N$ k# c
mount [-fnrsvw] [-t vfstype] [-o options] device dir6 F/ j6 r t( @. S5 u2 Y
! Q+ B. m- i9 I/ ?! {. g# K& `, uQ:所有的磁盘分区都必须被挂载上才能使用,那么我们机器上的硬盘分区是如何被挂载的?
$ R+ v, T! w4 u5 t
- H8 j5 U2 z, s+ Q3 @; C2 oA:这主要是它利用了/etc/fstab文件。每次内核加载它知道从这里开始mount文件系统。每次系统启动会根据该文件定义自动挂载。若没有被自动挂载,分区将不能使用。 如下是我的/etc/fstab的定义,主要是根据装机的分区来的:
4 D) B1 L2 v/ i: |3 B/ w* _* F6 Z- X1 R
8 R' [8 \6 @& Y1 ~- A8 j1 Z# <file system> <mount point> <type> <options> <dump> <pass>
0 v6 c' _9 d; F4 h3 Y5 a; x! N$ o4 N( e+ S4 \3 C
proc /proc proc defaults 0 0
7 `7 _& Q/ G+ l4 O0 v% Q8 ]9 {+ M3 O- ^& n; S% h6 z
#/dev/sda1被自动挂载到 /
6 ^) u1 T/ I/ l. U+ h" o$ }& T" c8 I2 O" D" W1 A1 U
UUID=cb1934d0-4b72-4bbf-9fad-885d2a8eeeb1 / ext3 relatime,errors=remount-ro 0 1
0 e7 n5 S4 I/ _! C; v1 j0 A# {. p; d3 r1 N/ a4 V
# /dev/sda5 被自动挂载到分区/home
3 l( R- r) W" L4 J6 e
9 g4 T$ [# g9 k( d) e) ?# uUUID=c40f813b-bb0e-463e-aa85-5092a17c9b94 /home ext3 relatime 0 2
4 A* _# Z4 Q1 [. Q8 t& o( |) R7 I" V) X" o0 X
#/dev/sda7 被自动挂载到/work! a a! D) k* e6 ~" Q) v9 w
' f5 a- Q" m) ]; p* q) Q
UUID=0f918e7e-721a-41c6-af82-f92352a568af /work ext3 relatime 0 2" ?, X- t" @3 [( P% ]
5 G& y$ _' l/ }
#分区 /dev/sda6被自动挂载到swap+ o% l5 r; F) U! W B# z) ^2 c0 U
5 ~6 Q3 l" c5 NUUID=2f8bdd05-6f8e-4a6b-b166-12bb52591a1f none swap sw 0 0
1 [9 l7 M0 g$ j$ I' U% s, X" a; k; e9 y" v0 G Z1 h
7 T3 k* M2 v, V, n; Y0 P y+ v" X) n* t- O5 i' [9 u# y% g
Q:移动硬盘如何挂载?如何挂载一个新的分区?
+ p6 r$ h2 {0 z; P0 e; o+ A x# v- k& E9 O! d, ` ]
移动硬盘有驱动模块会自动挂载,如果有个新硬盘,要先进行分区,并通过mount命令挂载到某个文件夹。如果要自动挂载则可以修改/etc/fstab文件.
$ f' |1 m) ]( D4 I7 v
+ K& V$ n3 [: w. _3 v: X% cNFS简介:NFS相信在很多地方都有广泛使用,是一个非常好的文件共享方式。我们公司所使用的上传服务就是把文件上传到某台网络服务器上,中间就是通过NFS实现。0 S4 l9 p& V' q7 b
" i7 V" m6 c/ g- L
使用NFS客户端可以透明的地访问服务器端的文件。NFS也是通过mount来实现,底层是通过NFS通信协议实现。基本原理:
( u# A) r: c! Q4 b% u* t
! h- [5 K) R, ] _9 W, F, N
5 l# X7 `: y+ u% [+ U3 L6 |) E
* [1 i5 h7 l0 u! N, t9 y
图2:NFS基本原理6 d j* F4 s% G A1 u0 C" `; g
R( G/ S# g9 n5 K, L$ J; ~! ^ * h- j& r. H2 W2 K8 u
8 K' G, Q6 m4 h% @0 r2 f4 g/ i
Ubuntu下面Ubuntu下的例子
# y/ t9 Z z. z1 o! C8 T- y) _3 F* P
服务端:# W2 H; f, |! X3 n( _. z) p
0 V* r- f$ G; B% E4 w; w# \/ h, d
$apt-get install nfs-kernel-server
$ u. P" K [- [. I& R& o) q: ]4 h6 @6 e; h, t4 c9 _# E, i' X1 S4 L- R
vi /etc/exports 添加nfs目录: /personal/nfs_share* K |3 o" i& P0 F! s6 l _
. R7 ]* N, I4 x V" H1 p5 ]; g/ M
10.1.60.34(rw,sync,no_root_squash)
) ^# ~' b5 d8 _2 e% q
|% T2 @$ j/ ^5 L$sudo exportfs -r
7 S) P0 x6 e; R, Q9 O+ N1 s
6 D7 G" G2 c, b/ B0 K$sudo /etc/init.d/portmap start
4 F/ q4 Q* ~* H& e) i0 G7 a2 z8 f T W( p" A2 A k
$sudo /etc/init.d/nfs-kernel-server start
' Y# b; o" p, G+ O, _6 j2 N
4 _4 X4 Q0 D/ C4 ~客户端:6 Y: w! I( k/ @4 W/ y+ ^
0 r( ]' g/ |8 B4 r
$sudo apt-get install nfs-common
2 j3 c' ^ @4 @
& a% x$ F7 R( x1 Y3 V: C( {6 c$sudo mount 10.19.34.76:/personal/nfs_share ~/nfsshare例子:% _6 g2 g( {- G, {3 e2 m5 D3 V
3 I. I! y. n7 E7 a# `: K& ? q6 C7 y: u' j5 y
* v8 L6 N1 m$ T& }) t- s' X) B+ l; J
3.文件类型" _9 f9 ~! T3 l3 ~- T* _2 M3 w
' y; D7 w$ q1 e/ ELinux下面的文件类型主要有:
: y8 c! r% O/ ^6 U H1 @6 _* y6 u" }7 B4 w0 ?. s2 f
a) 普通文件:C语言元代码、SHELL脚本、二进制的可执行文件等。分为纯文本和二进制。
! c9 ]- s; r3 l5 J$ F
8 O# q2 g+ ~5 P6 Q3 E/ I/ Qb) 目录文件:目录,存储文件的唯一地方。
2 C" |4 U; k. `3 S3 W' v
|: f" F" P b% f$ F' |c) 链接文件:指向同一个文件或目录的的文件。
4 v6 p/ P& q/ P. u
6 `2 g9 [+ u$ j/ zd) 特殊文件:与系统外设相关的,通常在/dev下面。分为块设备和字符设备。
3 k6 P; [0 G: ~4 @+ G' M7 i" ~/ T
+ A0 H2 k0 g2 c3 h+ q2 Y可以通过ls –l, file, stat几个命令来查看文件的类型等相关信息。
, ~: r* Z3 X2 y0 ~; f8 I5 w+ B# k3 L3 u8 n7 ~" K5 F! K5 o
# z! Z$ C+ A2 w4.文件存储结构' [& M* Q7 W# x
1 Z f+ N3 U4 E0 |5 o: \Linux正统的文件系统(如ext2、ext3)一个文件由目录项、inode和数据块组成。
# ~" P$ n. T3 R" C
$ X' n( \( h) B( A9 a/ ^目录项:包括文件名和inode节点号。) J- t! R4 P! z+ Z7 O% m3 w& ?! J
C' ^& r+ w/ Y9 U' d, b- D7 PInode:又称文件索引节点,是文件基本信息的存放地和数据块指针存放地。
U" ?+ B3 s% w/ _ V. s6 H) j+ W% m; e8 P
数据块:文件的具体内容存放地。( q8 a$ V& v0 E1 {
/ _ }0 d* I7 ?+ n0 B: W; v5 j
. J6 W) z8 ~ V$ t$ g1 Z: s ULinux正统的文件系统(如ext2、3等)将硬盘分区时会划分出目录块、inode Table区块和data block数据区域。一个文件由一个目录项、inode和数据区域块组成。Inode包含文件的属性(如读写属性、owner等,以及指向数据块的指针),数据区域块则是文件内容。当查看某个文件时,会先从inode table中查出文件属性及数据存放点,再从数据块中读取数据。1 x8 w( `0 b e# s! S. ^; B
& k, R+ j0 f# y" }6 v% s
站在2w英尺视图,文件存储结构大概如下:
! v5 W5 W# \0 T" q: d) _9 D. a
$ v. _! g! z1 {# b) l! O1 G
: G6 H. B0 X* R& ]( e8 V
$ ]4 B& E5 O @# I
图3:文件存储结构2w英尺视图
, T, {* q, O! o+ q( G; N" P$ x7 ^
# |) U! B8 y% c! y# }& p( A+ o7 |" y) t% S( s' Z3 @
其中目录项的结构如下(每个文件的目录项存储在改文件所属目录的文件内容里):
3 O- |& ]6 A& b4 o# j, v: l& ]) M+ }, F2 D5 @4 v+ j. S7 s3 Z
5 p! v# z+ u" J! y! R* I, f0 a. } P: i9 l& a4 }1 y
图4:目录项结构 ; _ r" f1 O+ d1 y) t
$ D3 q1 N' D0 `
/ h! A+ V7 O9 I3 M* j' Y其中文件的inode结构如下(inode里所包含的文件信息可以通过stat filename查看得到):
( u; d6 Y7 ^3 K) G7 g$ O9 O; `% O/ B7 P' q: F
% D* }- w, { v) F- g
) K0 ]5 D: e* B$ ]. p( t4 x' p) M图5:inode结构. B( _2 o+ N5 X8 h' E) n- J: x% @4 _
& f- z/ n$ B6 E$ s6 i8 ~3 O3 h
! l$ p8 N1 V8 z {6 W5 w. \以上只反映大体的结构,linux文件系统本身在不断发展。但是以上概念基本是不变的。且如ext2、ext3、ext4文件系统也存在很大差别,如果要了解可以查看专门的文件系统介绍。
; u' y$ _+ u' P1 X% I. C% ~
) g; G* ^# s( W2 y+ f9 c5.软连接、硬链接$ {8 u8 K0 S( H
( W- x: f7 o$ _; _软链接和硬链接是我们常见的两种概念:
7 ]3 o) @5 ?" s1 ^4 q8 c" \7 S4 ^/ x& T
硬连接:是给文件一个副本,同时建立两者之间的连接关系。修改其中一个,与其连接的文件同时被修改。如果删除其中任意一个其余的文件将不受影响。
& f' S$ ~* N! d5 B# a E
( G2 F- T5 S( _ y2 M) g' B软连接:也叫符号连接,他只是对源文件在新的位置建立一个“快捷(借用一下wondows常用词)”,所以,当源文件删除时,符号连接的文件将成为无源之水->仅仅剩下个文件名了,当然删除这个连接,也不会影响到源文件,但对连接文件的使用、引用都是直接调用源文件的。
A# Y# [- B3 v
+ C/ @ R" {/ Y# X. U具体关系可以看下图:
- I* i0 g" _. g7 `% W
/ ] I5 ^1 T/ \$ H
7 ^* G* w/ N( G/ C9 n7 P4 X( m0 W4 D( g1 V/ W
图5:软链接和硬链接
) t* T" j* f- q& n/ \
H% \5 E6 d! d" j F6 T) a: q" S, P
从图上可以看出硬链接和软链接的区别:" k% l) b$ b5 @) T' |. M2 n5 _1 j
. J' B( b4 h- N8 J: l1:硬链接原文件和新文件的inode编号一致。而软链接不一样。
7 X; ?. ^3 G( ~3 a$ V3 X, B7 b, L: P* ]
2:对原文件删除,会导致软链接不可用,而硬链接不受影响。! n& p' Z2 g4 i( l
2 x# g! Q* D1 d6 ^6 ^, g: M& F) l
3:对原文件的修改,软、硬链接文件内容也一样的修改,因为都是指向同一个文件内容的。
; f- A) a6 t4 ]$ |# J, p+ s0 F. X% p) E; v) N. R
7 ^: ^2 {* q2 L0 |. d! L
1 S% n# \6 w$ y4 v6.文件目录管理命令
" v* o' M9 _* O0 t) N$ E w1 v0 r
磁盘和文件空间- E9 [' q8 s- a D) u9 E7 S
9 [: W1 J/ S4 P1 g: B/ j+ bfdisk df du
1 J# Q g h5 G1 x7 N; D4 ?* |& j: Z6 @' d
文件目录与管理
! V; ]& M0 v3 y+ w
$ j$ C& S) a% m6 h5 Ccd pwd mkdir rmdir ls cp rm mv. a1 f. ~4 W& A* v) h0 I$ p
' a" |# A6 ~2 i7 j) E
查看文件内容9 _# Y; K9 r Z5 d: [. Q" @! J0 b
+ Z! k5 o, Y F# a
cat:
R: x* i% s Z' _/ g w, ~cat [file]
' M! V" v. s8 v0 I! c" F查看文件的内容。全程式concatenate的意思,将文件内容连续输出到屏幕上。第一行到最后一行显示。
4 d' P" @$ a" q1 v& W- m8 ntac:
( x; x- `' F/ H: X: g4 y$ L4 utac [file], P8 }& H! s5 D( T$ J
和cat刚好相反 是从最后一行到第一行的方式查看。
1 [8 Z1 q e9 x; d0 C* l& W0 \
5 W* h# \" A }, ^$ V0 Ncat有个比较不好的地方时当文件比较大时候没办法看清楚,这个时候可以用more或者Less命令。
) _$ Q2 o) q1 p7 w2 x+ }6 k9 g$ K8 V
& r8 A f2 p& d2 Fmore:
, o3 v. D1 P, G5 Hmore [file]
0 X+ X" I/ A9 ] Z. _如果使用grep或者find等命令时,可以配合使用more一页一页的查看。如果看到一半想退出,则敲入’q’即可退出。
6 I# R/ P5 A# Dless:
# J2 J d2 J! m* z; qless [file]. `6 G: r9 i( f0 b! E- U
less比more更有弹性,可以上下翻页。
/ K- U8 l" Z6 y" f& A! L9 q8 H" E7 F
如果只想读取文件的头几行或者文件的末尾几行,可以用head或tail.
9 q g" @- Y6 b1 thead –n [file]:读取文件的前n行。
4 q% `! ]9 i! l! s0 ltail –n [file]:读取文件末尾n行。
$ {5 V" t2 {1 `, ?8 X; D. G5 A% J/ ^. k4 c& d9 N2 u* G7 w% i
以上命令都是用于查看字符文件,二进制文件出来的都是乱码,要看二进制文件的内容,可以用od命令,如查看一个MP3文件里面的内容:
8 L& h V4 N' [7 F7 @4 @od shijiemori.mp3' }# B8 @* [2 [, Q8 ?
: \# M0 Z: Q" j6 W! b( l
8 o9 x1 N- o) E5 R; g文件目录与权限
, e( h; |, J) A1 r4 Z% {3 E. j
: A, m5 K1 X1 `9 c! Bchmod chown chgrp umask
2 ~9 R' ]( D" B% c2 k2 M/ m+ h# R3 p( B7 T0 U8 i* X. l
文件查找
6 N0 G6 ^3 S, s9 @: F7 H) @$ {
! d( P; S# c; @( E1 K4 W, Nwhich:
4 R! S, `7 D+ bwhich [filename]
, k+ w; T" R- { n该命令用于查询通过PATH路径到该路径内查找可执行文件。# \3 R7 G1 q n. [
如:Which passwd:查找可执行文件passwd# S& G/ @( a* w% ^' q4 z& @* `
whereis:
; C6 I2 H5 w0 ]& |9 ?! Nwhereis [-bmsu] [keyword]
) l- {% _: X, }% g该命令用于把相关字的文件和目录都列出来。(Linux 会将文件都记录在一个文件数据库里面,该命令式从数据库去查询,所以速度比较快,Linux每天会更新该数据库)
$ m) K. `9 w3 k2 g# Z- ~* Y
" q9 \7 g0 e- ^: o: ~# olocate:$ n' M7 p: u+ c4 H. A4 p
locate [filename]
V6 V" O( ~% y8 Z! e该命令用于把相关字的文件和目录都列出来。查找数据特别快,也是通过数据库方式来查询。但是数据库一周更新一次,所以可能有些存在数据查不到。可以去修改配置文件。4 M4 n' V$ a+ J8 a
9 U; q) k) ~( ^$ mfind:8 D: o9 |$ t4 j1 I% |* r* j" n
find [path] [参数] [keyword]
/ a3 V& A5 `* S6 u( h4 n4 h该命令用于在指定路径下查找文件。不是通过数据来查询,所以速度会比较慢。 & T! A# C1 u- x4 V/ |% K# Y5 I+ J( n
0 T7 b4 L2 G6 h! ^6 g9 R3 T- E+ I' b7.常见目录解释
2 M' k4 R0 ~- }1 ] I, J
/ D3 ?7 S( u6 ^1 nLinux各种发行版的目录结构基本一致,各个目录简单介绍如下:+ P4 j" U( b D! k/ M; a
$ B& Y: S8 U; g/ @: O) K! r" c% v9 L2 s 6 M/ j8 I. f' r4 N7 }. F/ ?' O
目录 | 描述 | / | 根目录 | /bin | 做为基础系统所需要的最基础的命令就是放在这里。比如 ls、cp、mkdir等命令;功能和/usr/bin类似,这个目录中的文件都是可执行的,普通用户都可以使用的命令。 | /boot | Linux的内核及引导系统程序所需要的文件,比如 vmlinuz initrd.img 文件都位于这个目录中。在一般情况下,GRUB或LILO系统引导管理器也位于这个目录;启动装载文件存放位置,如kernels,initrd,grub。一般是一个独立的分区。 | /dev | 一些必要的设备,声卡、磁盘等。还有如 /dev/null. /dev/console /dev/zero /dev/full 等。 | /etc | 系统的配置文件存放地. 一些服务器的配置文件也在这里;比如用户帐号及密码配置文件; /etc/opt:/opt对应的配置文件 /etc/X11:Xwindows系统配置文件 /etc/xml:XML配置文件 …… | /home | 用户工作目录,和个人配置文件,如个人环境变量等,所有的账号分配一个工作目录。一般是一个独立的分区。 | /lib | 库文件存放地。bin和sbin需要的库文件。类似windows的DLL。 | /media | 可拆卸的媒介挂载点,如CD-ROMs、移动硬盘、U盘,系统默认会挂载到这里来。 | /mnt | 临时挂载文件系统。这个目录一般是用于存放挂载储存设备的挂载目录的,比如有cdrom 等目录。可以参看/etc/fstab的定义。 | /opt | 可选的应用程序包。 | /proc | 操作系统运行时,进程(正在运行中的程序)信息及内核信息(比如cpu、硬盘分区、内存信息等)存放在这里。/proc目录伪装的文件系统proc的挂载目录,proc并不是真正的文件系统,它的定义可以参见 /etc/fstab 。 | /root | Root用户的工作目录 | /sbin | 和bin类似,是一些可执行文件,不过不是所有用户都需要的,一般是系统管理所需要使用得到的。 | /tmp | 系统的临时文件,一般系统重启不会被保存。 | /usr | 包含了系统用户工具和程序。 /usr/bin:非必须的普通用户可执行命令 /usr/include:标准头文件 /usr/lib:/usr/bin/ 和 /usr/sbin/的库文件 /usr/sbin:非必须的可执行文件 /usr/src:内核源码 /usr/X11R6:X Window System, Version 11, Release 6. | /srv | 该目录存放一些服务启动之后需要提取的数据 |
M4 U$ H/ V" O+ ` H1 T7 H4 P0 ]; h; ~2 A
7 H8 X, q5 b, N; G
$ E+ v/ x6 o4 E1 g- \9 D
$ U1 j8 ]+ S( b+ s6 f$ H ? Q! Y, o1 I# b8 F8 W
2 d: l6 q9 a1 g. c6 V# n8 D5 [
& J* j: M6 \$ Q3 ~$ A9 p4 B* I
|
|