0%

打印图形

打印锥形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#给定一个数字和一个符号,打出锥形
import math
l = input().split()
n = math.floor(math.sqrt((int(l[0])+1)/2))

for i in range(-n,n+1):
if i < 0 :
x = -i
print(" "*(n-x)+l[1]*(2*x-1))
elif i>1:
x = i
print(" "*(n-x)+l[1]*(2*x-1))
else:
print(end="")
z = n**2*2-1
print(int(l[0])-z)
31 *
*******
 *****
  ***
   *
  ***
 *****
*******
0
1
2
3
4
5
6
#坐标法打印锥形
n = 7
e = 7//2
for i in range(-e,e+1):
x = -i if i < 0 else i
print(" "*(e-x)+ "*" * (2*x+1))
*******
 *****
  ***
   *
  ***
 *****
*******

打印菱形

1
2
3
4
5
6
7
8
#打印菱形
n = 7
e = -(n//2)
for i in range(e,n+e):
if i<=0:
print(" "*abs(i)+"*"*(n+2*i))
else :
print(" "*i+"*"*(n-2*i))
   *
  ***
 *****
*******
 *****
  ***
   *

打印闪电

1
2
3
4
5
6
7
8
9
10
#打印闪电
n = 7
e = n//2
for i in range(-e,e+1):
if i<0:
print(" "*abs(i)+ "*" * (e+i+1))
elif i == 0:
print("*"*n)
else:
print(" "*3+"*"*(e-i+1))
   *
  **
 ***
*******
   ***
   **
   *

打印正方形

1
2
3
4
5
6
7
8
#打印一个边长为n的正方形
var = int(input(">>"))
for i in range(var):
if i ==0 or i == var-1:
print("*"*var)
else:
print("*" + " "*(var-2) + "*")

>>4
****
*  *
*  *
****
1
2
3
4
5
6
n = 4
for i in range(n):
if i % (n-1)==0:
print("*"*n)
else:
print("*"+" "*(n-2)+"*")
****
*  *
*  *
****
1
2
3
4
5
6
7
8
#打印一个边长为n的正方形
n = int(input(">>"))
e = -(n//2)
for i in range(e,n+e):
if i == e or i == n+e-1:
print ("*"*n)
else :
print("*"+" "*(n-2)+"*")
>>6
******
*    *
*    *
*    *
*    *
******
1
2
3
4
5
6
7
8
9
10
11
12
13
#统计你输入的每个数字有多少个,按照升序输出
l = input().split()
l = int(l[0])
num = list()
num1 = [0]*10
while l>0:
x = l % 10
num1[x] += 1
num.append(x)
l //=10
for i in range(10):
if num1[i] !=0:
print("{}:{}".format(i,num1[i]))
1231013
0:1
1:3
2:1
3:2
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
31
32
#读数字
zz = input().split()
a = int(zz[0])
l = ['ling','yi','er','san','si','wu','liu','qi','ba','jiu','fu']
i = 0
li =list()
x = a
y = abs(a)
while abs(x)>0:
x = abs(x)//10
i += 1
for j in range(i):
m = 10**(i-1)
y = y// m
li.append(y)
i -= 1
y = abs(a) % m

length = len(li)
if a>0:
for i in li:
if int(i)<length:
print("{}".format(str(l[i])),end=" ")
else:
print("{}".format(str(l[i])),end="")
else:
print(str(l[10]),end=" ")
for i in li:
if int(i)<length:
print("{}".format(str(l[i])),end=" ")
else:
print("{}".format(str(l[i])),end="")
-123
fu yi er san

三个数排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#只用判断,三个数排序
l = list()
for i in range(3):
l.append(int(input(">>")))
if l[0] > l[1]:
if l[0] > l[2]:
if l[1]>l[2]:
print(l[0],l[1],l[2])
else:
print(l[0],l[2],l[1])
else:
print(l[2],l[1],l[0])
else :
if l[0] > l[2]:
print(l[1],l[0],l[2])
else:
if l[1]<l[2]:
print(l[2],l[1],l[0])
else:
print(l[1],l[2],l[0])

>>1
>>3
>>2
3 2 1
1
2
3
4
5
6
7
8
9
10
11
#使用max函数,三个数排序
l = list()
for i in range(3):
l.append(int(input(">>")))
while l:
if len(l) == 1:
print(l[0])
break
m = max(l)
print(m)
l.remove(max(l))
>>2
>>3
>>1
3
2
1
1
2
3
4
5
6
#使用sort()函数,三个数排序
l = list()
for i in range(3):
l.append(int(input(">>")))
l.sort()
l
>>1
>>4
>>2

[1, 2, 4]

冒泡法排序(重要)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#优化后的冒泡法(重要)
#l=[1,9,8,5,6,7,4,3,2]
l=[1,2,3,4,5,6,7,9,8]
length = len(num)
count = 0
count_swap = 0

for i in range(length):
flag = False
for j in range(length-i-1):
count += 1
if l[j] > l[j+1]:
tmp = l[j]
l[j] = l[j+1]
l[j+1] = tmp
flag = True
count_swap += 1
if not flag:
break
print(l,count,count_swap)

[1, 2, 3, 4, 5, 6, 7, 8, 9] 15 1
  • 优化点:可以设定一个标记判断此轮是否有数据交换发生,如果没有发生交换,可以结束排序,如果发生交换,则进行下一轮
  • 最差的排序情况是,初始顺序和目标顺序完全相反,遍历次数1,…,n-1之和n*(n-)/2
  • 最好的排序情况是,初始顺序与目标顺序完全相同,遍历次数n-1
  • 时间复杂度O(n^2)

二分法查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#二分法查找
def banery_serch(list,item):
low = 0
high = len(list)-1
while low <= high:
mid = (low+high)//2
giss = list[mid]
if item == mid:
print(Ture)
elif item > mid:
high = mid - 1
else:
low = mid +1
my_list = [1,2,3,5,2,6,4,7,9]

给定一个数,输入为几位数,并依次输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 #给定一个数,输入为几位数
num = int(input(">>"))
i = 0
flag = False
while num > 0:
a = num%10
print("a",a,end=" ")
num = num//10

#给定一个数字判断有几位
num = int(input(">>"))
i = 1
while num >= 10:
num = num/10
i += 1
print("i",i)
>>1234
a 4 a 3 a 2 a 1 
1
2
3
4
5
6
7
8
9
10
11
12
13
 #给定一个数,并依此输出\n
x = '02300'
x = int(x)
n = 5
w = 10000
flag = False
for i in range(n):
y = x // w
if flag or y:
flag = True
print(y,end=" ")
x = x % w
w = w //10
2 3 0 0 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
c = int('00211')
w = 10000
length = 5
flag = False
while w:
t = c //w
if flag:
print(t,end=" ")
else:
if t:
print(t,end=" ")
flag =True
else:
length -=1
c %= w
w //=10
2 1 1 

求均值

1
2
3
4
5
6
7
8
9
10
11
a = int(input(">>")) 
l = list()
num = 0
for i in range(a):
x = int(input('>>'))
if x == None:
break
else:
l.append(x)
num = num+l[i]
print(num/len(l))
>>3
>>1
1.0
>>3
2.0
>>4
2.6666666666666665

打印乘法表

打印倒乘法表

1
2
3
4
5
6
#打印倒乘法表
for i in range(1,10):
print("\t"*(i-1),end="")
for j in range(i,10):
print ("{}x{}={:<{}}".format(i,j,i*j,2 if j<2 else 3),end=" ")
print()
1x1=1  1x2=2   1x3=3   1x4=4   1x5=5   1x6=6   1x7=7   1x8=8   1x9=9   
       2x2=4   2x3=6   2x4=8   2x5=10  2x6=12  2x7=14  2x8=16  2x9=18  
               3x3=9   3x4=12  3x5=15  3x6=18  3x7=21  3x8=24  3x9=27  
                       4x4=16  4x5=20  4x6=24  4x7=28  4x8=32  4x9=36  
                               5x5=25  5x6=30  5x7=35  5x8=40  5x9=45  
                                       6x6=36  6x7=42  6x8=48  6x9=54  
                                               7x7=49  7x8=56  7x9=63  
                                                       8x8=64  8x9=72  
                                                               9x9=81  

打印正乘法表

1
2
3
4
5
#打印九九乘法表:
for i in range(1,10):
for j in range(1,i+1):
print("{}x{}={}\t".format(j,i,i*j),end=" ")
print()
1x1=1     
1x2=2     2x2=4     
1x3=3     2x3=6     3x3=9     
1x4=4     2x4=8     3x4=12     4x4=16     
1x5=5     2x5=10     3x5=15     4x5=20     5x5=25     
1x6=6     2x6=12     3x6=18     4x6=24     5x6=30     6x6=36     
1x7=7     2x7=14     3x7=21     4x7=28     5x7=35     6x7=42     7x7=49     
1x8=8     2x8=16     3x8=24     4x8=32     5x8=40     6x8=48     7x8=56     8x8=64     
1x9=9     2x9=18     3x9=27     4x9=36     5x9=45     6x9=54     7x9=63     8x9=72     9x9=81     
1
2
3
4
5
#打印九九乘法表:
for i in range(1,10):
for j in range(1,i+1):
print(j,"x",i,"=",j*i," ",end=" ")
print()
1 x 1 = 1   
1 x 2 = 2   2 x 2 = 4   
1 x 3 = 3   2 x 3 = 6   3 x 3 = 9   
1 x 4 = 4   2 x 4 = 8   3 x 4 = 12   4 x 4 = 16   
1 x 5 = 5   2 x 5 = 10   3 x 5 = 15   4 x 5 = 20   5 x 5 = 25   
1 x 6 = 6   2 x 6 = 12   3 x 6 = 18   4 x 6 = 24   5 x 6 = 30   6 x 6 = 36   
1 x 7 = 7   2 x 7 = 14   3 x 7 = 21   4 x 7 = 28   5 x 7 = 35   6 x 7 = 42   7 x 7 = 49   
1 x 8 = 8   2 x 8 = 16   3 x 8 = 24   4 x 8 = 32   5 x 8 = 40   6 x 8 = 48   7 x 8 = 56   8 x 8 = 64   
1 x 9 = 9   2 x 9 = 18   3 x 9 = 27   4 x 9 = 36   5 x 9 = 45   6 x 9 = 54   7 x 9 = 63   8 x 9 = 72   9 x 9 = 81   

一到五阶乘之和

1
2
3
4
5
6
7
8
#一到五阶乘之和
a= 1
sum = 0
for i in range(1,6):
a *= i
sum += a
i += 1
print("sum =",sum )
1
2
3
4
5
#100内的所有奇数之和
a = 0
for i in range (1,100,2):
a = a+i
print("a=",a)
a= 2500
1
2
3
4
5
6
#100内的所有奇数之和
a = 0
for i in range(1,100,2):
if not i%2 == 0:
a += i
print("a=",a)

斐波那契数列

打印100以内的斐波那契数列

1
2
3
4
5
6
# 打印100以内的斐波那契数列
i = 0
j = 1
while i < 100:
print(i,end=" ")
i,j=j,i+j
0 1 1 2 3 5 8 13 21 34 55 89 
1
2
3
4
5
6
7
8
# 打印100以内的斐波那契数列
i = 0
j = 1
while i<=100:
print (i,end=" ")
k = i + j
i = j
j = k
0 1 1 2 3 5 8 13 21 34 55 89 

求斐波那契数列第101项

1
2
3
4
5
6
7
8
9
#求斐波那契数列第101项
i = 0
j = 1
m = 1
while m<=101:
i, j = j, i + j
m += 1

print(i)
573147844013817084101

求素数

寻常法

1
2
3
4
5
6
7
8
9
10
11
12
13
#求10万内的所有素数
import math
n = 100000
count = 1
for i in range(3,n,2):
if i > 10 and i % 5 ==0:
continue #所有大于10 的素数中,个位数只有1,3,7,9,所以此处筛出5结尾的
for j in range(3,int(math.sqrt(i)+1),2):
if i % j ==0:
break
else:
count += 1
print (count)
9592

利用素数列表,空间换时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#存储质数
#合数一定可以分解为几个质数的乘积,2是质数
#质数一定不能整除1和本身之内的整数
#使用质数来取模比利用基数取模计算次数更少
import math
n = 100000
count = 1
primenumber = [2]
for i in range(3,n,2):
flag = False
edge = math.sqrt(i)
for j in primenumber:
if i % j == 0:
flag = True
break
if j > edge:
break
if not flag:
count += 1
primenumber.append(i)
print(count)

利用孪生素数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#大于3 的素数只有6N-1和6N+1两种形式,如果6N-1和6N+1都是素数便叫作孪生素数
import math
n = 100
count = 2
primenumber = [2,3]
step = 2
x = 5
while x < n:
for i in range(3,int(math.sqrt(x)+1),2):
if x % i == 0:
break
else:
count += 1
primenumber.append(x)
x += step
step = 4 if step == 2 else 2
print(count)
print(primenumber)

埃式筛素数

1
2
3
4
5
6
7
8
9
10
11
12
#埃式筛素数
def eratosthenes(n):
IsPrime = [True] * (n + 1)
IsPrime[1] = False
for i in range(2, int(n ** 0.5) + 1):
if IsPrime[i]:
for j in range(i * 2, n + 1, i):
IsPrime[j] = False
return {x for x in range(2, n + 1) if IsPrime[x]}

if __name__ == "__main__":
print (eratosthenes(100))
{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}

杨辉三角

计算杨辉三角,普通法

1
2
3
4
5
6
7
8
9
10
#计算杨辉三角 普通法
triangle = [[1],[1,1]]
for i in range(2,6):
swap = triangle[i-1]
cul = [1]
for j in range(i-1):
cul.append(swap[j]+swap[j+1])
cul.append(1)
triangle.append(cul)
triangle

计算杨辉三角 补0法

1
2
3
4
5
6
7
8
9
10
#计算杨辉三角 补0法
triangle = [[1]]
n = 7
for i in range(1,n):
swap = triangle[i-1]+[0]
cul = [1]
for j in range(len(swap)-1):
cul.append(swap[j]+swap[j+1])
triangle.append(cul)
print(triangle)

杨辉三角,对称法

1
2
3
4
5
6
7
8
9
10
11
12
#杨辉三角,对称法
n=6
triangle = [[1],[1,1]]
for i in range(2,n):
tmp = triangle[-1]
cul = [1] * (i+1)
for j in range(i//2):
cul[j+1] = tmp[j]+tmp[j+1]
if i != 2j:
cul[-j-2] = cul[j+1]
triangle.append(cul)
triangle

中点的确定
[1]
[1,1]
[1,2,1]
[1,3,3,1]
[1,4,6,4,1]
[1,5,10,10,5,1]
把整个杨辉三角看成一个左对齐的二维矩阵。
i == 2时,在第3行,中点的列索引j==1
i == 3时,在第4行,无中点
i == 4时,在第5行,中点的列索引j==2
得到以下规律,如果i==2j,则有中点

杨辉三角,单列表方法

1
2
3
4
5
6
7
8
9
10
11
12
13
#杨辉三角,单列表解决
n = 6
row = [1] * n
for i in range(n):
z = 1
offset = n - i
for j in range(1,i//2+1):
val = z + row[j]
z = row[j]
row[j] = val
if i != 2*j:
row[-j - offset] = val
print(row[:i+1])

基础语法:

一.冯诺依曼体系架构:

五大部件:
  • CPU:包括运算器和控制器,CPU只和一件设备,内存打交道。

  • 运算器:是完成各类算术运算,逻辑运算,数据传输等数据加工处理。数据是通过总线传输,总线则是使用电信号传输。

  • 控制器:是用于控制程序的执行。

  • 存储器memory:用于记忆程序和数据,例如内存(缺点:掉电易失数据)

  • I 输入设备:将数据或者程序数据传输到计算机中,例如键盘,鼠标。

  • O 输出设备:将数据或者程序的处理结果展示给用户,例如显示显示器,打印机。

  • CPU有三级cache,寄存器,cpu临时要计算的数据存储在寄存器中,寄存器的频率和CPU几乎同频率的运算频率,多级缓存则逐级递减。


高级语言和低级语言之间需要一个转换的工具:编译器,解释器。

编译语言:把源代码转换成目标机器的CPU指令。例如:C,C++。
解释语言:解释后转换成字节码,运行在虚拟机上,解释器执行中间代码(bytecode)。例如:java,python,C#等语言。

二.程序:算法 + 数据结构

  • 数据是一切程序的核心

  • 数据结构是数据在计算机中的类型和组织方式

  • 算法是处理数据的方式,算法有优劣之分

  • 算法运行时间并不以秒为单位,算法运行时间是从其增速的角度度量的。

python语言类型:

python是动态语言、强类型语言。
python中:赋值即定义,如果一个变量已经定义,赋值相当于重新定义。(动态语言的特性)

语言的分类:
  1. 静态编译语言:
    事先声明变量类型,类型不能再改变
    编译时检查
  2. 动态编译语言:
    不用事先声明类型,随时可以赋值为其他类型
    编程时不知道是什么类型,很难推断。
  3. 强类型语言:
    • 不同类型之间的操作,必须先强制类型转换为同一类型。例:print(’a’+1)
      弱类型语言:
    • 不同类型之间操作,自动隐式转换,Javascript中console.log(1,+’a’)

重点:什么是动态语言,什么是强类型语言,强弱怎么区分?
强弱是一个相对概念,用一个字符串加上一个数字就可判定。


python解释器:
  • 官方Cpython:c语言开发,广泛的python解释器

  • IPython:一个交互式,功能增强的Cpython

  • PyPy:python语言写的python解释器,JIT(jist type)技术,动态编译python代码。(效率比cpython高)。

  • Jython:python的源代码编译成java的字节码,跑在JVM上。

  • IronPython:与Jython类似,运行在.net平台上的解释器,python代码被编译成.net的字节码。

运算符优先级:
  • 算术运算符 > 位运算符 > 身份运算符 > 成员运算符 > 逻辑运算符 > 赋值运算符
  • 单目运算符 > 双目运算符

(JVM、PVM)内存管理:
  1. 变量无须事先声明,也不需要指定类型(动态语言的特性)
  2. python编程中一般无须关心变量的存亡,一般也不用关心内存的管理。
  3. python使用引用技术记录所有对象的引用数:
    • 当对象引用数变为0,它就可以被垃圾回收(GC)的自动回收机制回收(不建议手动管理,会影响性能)
    • 计数增加:
      赋值给其他变量就增加引用计数,例如:x=3;y=x.
    • 计数减少:
      函数运行结束时,局部变量就会被自动销毁,对象引用计数减少
      变量被赋值给其他对象。例如:x=3,y=x(3的计数加一),x=4(4的计数加一,3的计数减一)

      注意:有关性能的时候,就要考虑变量的引用问题,切记尽量不要手动干预,但是该释放内存,还是尽量不释放内存,看需求。
      注意:垃圾回收还有包括规整,即碎片整理

  • 共享引用:多个变量引用一个对象
    • ==是判断内容是否相等
    • is是判断是否指向同一内存空间,使用id来查看内存地址
    • 界限为256,256以下的整数已被python缓存
    • 判断一个东西有多少在引用:
      1
      2
      import sys
      sys.getrefcount(4)
False等价

布尔值,相当于bool(value)

  • 空集合
  • 空字符串
  • 空字典
  • 空列表
  • 空元组
  • none对象
  • 0
列表、链表、队列、栈的区别

重点
下列四者区别和特点

  • 内存是线性编址的。
  1. 列表list:
    一个队列,一个排列整齐的队伍
    列表中的个体称作元素,由若干个元素组成列表
    元素可是是任意对象(数字,字符串,列表,元组,对象)
    列表内元素有顺序,可以使用索引。
    列表可以是一个可迭代对象
    列表是可变的,连续的内存中的顺序结构,通过偏移量在查询(检索起来快)
    “有顺序”“可索引”“可变”“可迭代”“线性结构”
    尽量不要使用remove和insert,比较耗时

  2. 链表:有序的在内存中分布散落,
    查询比列表慢,插入比列表快

  3. queue:队列,先进先出
    不是为了遍历

  4. stack:栈,后进先出

元组修改

一般对于返回None的都意味着没有新的产生,就都是就地修改

元组:一个有序的元素组成的集合,不可变对象
元组 + 元组,元组*数字,返回一个新元组。并不是改变原先的元组
元组是只读的

字符串:是一个字面常量,不可变,可迭代


运算符判断
-> 结果
6 or 2 > 1 -> 6
0 or 5 < 4 -> False
5 < 4 or 3 -> 3
2 > 1 or 6 -> True
3 and 2 > 1 -> True
0 and 3 > 1 -> 0
2 > 1 and 3 -> 3
3 > 1and 0 -> 0
print(1 or 2) -> 1
print(0 or 100) -> 100
print(1 and 2) -> 2
print(bool(2)) -> True
print(bool(-2)) -> True
print(bool(0) -> False

方法:

  • x or y x为 (True) 非零,则返回x
  • x and y x (True)非零,则返回y
  • 非零转换成bool True
  • 0转换成bool是False

拓展:while 1 的效率要比 while True高,因为Ture要先转换成1,然后再转化成二进制
网络传输,big:大端模式,
低字节放在高地址上就是大端模式
高字节放到低地址上就是小端模式
Windows小端模式 mac大端模式

python上下文:使用with方法不用每次都手动关闭文件

1
2
3
with open("file.xxx") as f:
for line in f.readlines():
print(line)

使用二进制写文件可以使用一个模块
写:pickle.dump(word,file)
读:pickle.load(file)


封装和解构:
  1. 封装:
    将多个值使用逗号分隔,结合在一起
    本质上返回了一个元组,只是省略了小括号
    t1 = (1,2) # 定义为元组
    t2 = 1,2 #将1,2封装成元组

  2. 解构
    把右边的元素解开,并顺序的赋给其他变量
    左边接纳的变量数要和右边解开的元素个数一致
    使用*变量名接收,但不能单独使用,被*变量名收集后组成一个列表
    例如: head,*mid,tail = “abcdefghijklmnopqrstuvwxyz”

例:

1
2
3
4
5
temp = a
a = b
b = temp
等价于
a , b = b , a

等号右边使用了封装,而左边使用了解构

set和线性结构
  • 线性结构的查询时间复杂度是O(n),即随着数据规模的增大而增大
  • set、dict等结构,内部使用hash值作为key,时间复杂度为O(1),查询时间与数据规模无关。
  • set的元素要求必须可哈希
    ​ 可变的数据结构不可哈希
    ​ 元素不可索引
    ​ set可以迭代
  • 线性结构:
    • 可迭代 for … in
    • len()可以获取长度
    • 通过下标可访问
    • 可以切片
  • 包括:列表、元组、字符串、bytes、bytearray
    不可变对象:元组、字符串、bytes
  • 可hash对象:
    数值型:int、float、complex
    布尔型:True、False
    字符串:string、bytes
    tuple,None
    以上都为不可变类型
  • 可变类型:list,dict,bytearray
  • 可迭代对象
    • 能够通过迭代一次次返回不同的元素的对象。
    • 所谓相同,不是指值是否相同,而是元素在容器中是否是同一个,例如列表中值可以重复的,[‘a’, ‘a’],虽然这个列表有2个元素,值一样,但是两个’a’是不同的元素
    • 可以迭代,但是未必有序,未必可索引
    • 可迭代对象有:list、tuple、string、bytes、bytearray、range、set、dict、生成器等
    • 可以使用成员操作符in、not in,in本质上就是在遍历对象

字典的遍历和移除:不能直接遍历删除字典,要使用一个容器记录一个这个字典的key,然后通过遍历key来从字典中删除。

权限判定可以将弄成集合加载到内存中进行集合计算,速度要比在数据库中操作对比快得多。比如说微博的redis

  • OrderedDict
    有序字典可以记录元素插入的顺序,打印的时候也是按照这个顺序输出打印
    3.6版本的Python的字典就是记录key插入的顺序(IPython不一定有效果)

  • 应用场景:

    • 假如使用字典记录了N个产品,这些产品使用ID由小到大加入到字典中

    • 除了使用字典检索的遍历,有时候需要取出ID,但是希望是按照输入的顺序,因为输入顺序是有序的

    • 否则还需要重新把遍历到的值排序


光盘、磁盘都是随机访问的

Linux基础-文件管理和重定向

1. 每一个分区都是一个独立存在的文件系统
2. 目录:路径映射符
3. 文件

文件有两种数据

  • 元数据:描述数据的数据属性 metadata
  • 数据:data

FHS:文件系统层级结构标准

4. Linux下的文件类型
  • -:普通文件
  • d:目录文件
  • b:块设备
  • c:字符设备
  • l:符号链接文件
  • p:管道文件pip,FIFO(first in,first out)
  • s:套接字文件:服务加IP端口,作为一个服务的入口。socket
5. 显示当前路径
  • 每个shell和系统进程都有一个当前的工作目录 
  • CWD:current work directory
  • 显示当前shell CWD的绝对路径
  • pwd: printing working directory
    • -P 显示真实物理路径
    • -L 显示链接路径(默认)
6. 绝对路径和相对路径

绝对路径:

  • 以正斜杠开始
  • 完整的文件的位置路径
  • 可用于任何想指定一个文件名的时候

相对路径名:

  • 不以斜线开始
  • 指定相对于当前工作目录或某目录的位置
  • 可以作为一个简短的形式指定一个文件名

注:

  • 基名:basename
  • 目录名:dirname
7. cd命令

cd 改变目录

  • 使用绝对或相对路径:
    • cd /home/wang/
    • cd home/wang
  • 切换至父目录 :cd ..
  • 切换至当前用户主目录: cd
  • 切换至以前的工作目录: cd -
  • 选项:-P
  • 相关的环境变量:
    • 显示环境变量:printenv
      • PWD:当前目录路径
      • OLDPWD:上一次目录路径
  • ~ :当前用户家目录
  • ~luo :用户luo家目录
  • ~+ :当前工作目录
  • ~- :前一个工作目录
8. 显示目录
  • 列出当前目录的内容或指定目录(显示的数据都是元数据)
  • 用法:ls [options][files_or_dirs]
  • 示例:
    • ls -a :包含隐藏文件
    • ls -l :显示额外的信息
    • ls -R :目录递归显示
    • ls -ld : 目录和符号链接信息
    • ls -1 :文件分行显示
    • ls –S :按从大到小排序
    • ls –t : 按mtime排序
    • ls –u :配合-t选项,显示并按atime从新到旧排序
    • ls –U : 按目录存放顺序显示
    • ls –X : 按文件后缀排序
9. 查看文件状态:显示当前文件的时间戳

命令:stat

  • 文件:metadata, data
  • 三个时间戳:
    • access time:访问时间,atime,读取文件内容
    • modify time: 修改时间, mtime,改变文件内容(数据)
    • change time: 改变时间, ctime,元数据发生改变

注意:
元数据发生变化,数据不一定变化
数据发生变化,元数据一定变化

10. 文件通配符(对文件名做通配)(glob、globing、wildcard)
  • * :匹配零个或多个字符
  • ? :匹配任何单个字符
  • [0-9] : 匹配数字范围
  • [a-z] :字母
  • [A-Z] :字母
  • [wang] : 匹配列表中的任何的一个字符
  • [^wang] : 匹配列表中的所有字符以外的字符
  • 预定义的字符类:(帮助:man 7 glob)
    • [:digit:]:任意数字,相当于0-9
    • [:lower:]:任意小写字母
    • [:upper:]:任意大写字母
    • [:alpha:]:任意大小写字母
    • [:alnum:]:任意数字或字母
    • [:blank:]:水平空白字符
    • [:space:]:水平或垂直空白字符
    • [:punct:]:标点符号
    • [:print:]:可打印字符
    • [:cntrl:]:控制(非打印)字符
    • [:graph:]:图形字符
    • [:xdigit:]:十六进制字符
11. touch命令:

touch [OPTION]... FILE...

  • -a 仅改变 atime和ctime
  • -m 仅改变 mtime和ctime
  • -t [[CC]YY]MMDDhhmm[.ss]
    指定atime和mtime的时间戳
  • -c 如果文件不存在,则不予创建

    例如:touch -m -t 201806300000.00 /etc/passwd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost ~]# stat /etc/passwd
File: `/etc/passwd'
Size: 1677 Blocks: 8 IO Block: 4096 regular file
Device: 803h/2051d Inode: 787752 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: (0/ root)
Access: 2017-04-10 18:57:44.311586312 +0800
Modify: 2017-04-10 18:48:32.693647980 +0800
Change: 2017-04-10 18:48:32.693647980 +0800
[root@localhost ~]# touch -m -t 201703300000.00 /etc/passwd
[root@localhost ~]# stat /etc/passwd
File: `/etc/passwd'
Size: 1677 Blocks: 8 IO Block: 4096 regular file
Device: 803h/2051d Inode: 787752 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2017-04-10 18:57:44.311586312 +0800
Modify: 2017-03-30 00:00:00.000000000 +0800
Change: 2017-04-10 14:13:22.439425983 +0800
12. 复制:所谓的复制就是创建一个新的空文件,然后在将源文件的数 据流读出来,然后写进去。

cp默认不复制目录下的内容,选项:-r:递归复制

1
2
3
4
1.cp [OPTION]... [-T] SOURCE DEST
2.cp [OPTION]... SOURCE... DIRECTORY
3.cp [OPTION]... -t DIRECTORY SOURCE...(2.3等同)
4.cp SRC DEST
  • SRC是文件:

    • 如果目标不存在:新建DEST,并将SRC中内容填充至DEST中
    • 如果目标存在:
      • 如果DEST是文件:将SRC中的内容覆盖至DEST中。
        ​ 基于安全,建议为cp命令使用-i选项。
      • 如果DEST是目录:在DEST下新建与原文件同名的文件,并 将SRC中内容填充至新文件中。
  • cp SRC… DEST

    • SRC…:多个文件
      • DEST必须存在,且为目录,其它情形均会出错;
  • cp SRC DEST

    • SRC是目录:此时使用选项:-r
      • 如果DEST不存在:则创建指定目录,复制SRC目录中所有文件 至DEST中;
      • 如果DEST存在:
        • 如果DEST是文件:报错
        • 如果DEST是目录
  • cp的常用选项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    -i:覆盖前提示	 –n:不覆盖,注意两者顺序
    -r, -R: 递归复制目录及内部的所有内容
    -a: 归档,相当于-dR --preserv=all
    -d:--no-dereference --preserv=links 不复制件,只 复制 链接名
    --preserv[=ATTR_LIST] (元数据信息)
    mode: 权限
    ownership: 属主、属组
    timestamp: (时间戳(atime、mtime不变)(cti会变))
    links:链接属性
    xattr:拓展属性
    context:保持selinux的安全属性
    all:以上所有
    -p: 等同--preserv=mode,ownership,timestamp
    -v: --verbose 显示提示信息
    -f: --force 强制
    -u:--update 只复制源比目标更新文件或目标不存在的文件
    --backup=numbered 目标存在,覆盖前先备份加数字后缀

cp命令中:具体的流程是:

分配一个空闲的inode号,在inode表中生成新条目,在目录中创建一个目录项,将名称inode编号关联
拷贝数据生成新的文件。

13. 移动和重命名文件
1
2
3
mv [OPTION]... [-T] SOURCE DEST
mv [OPTION]... SOURCE... DIRECTORY
mv [OPTION]... -t DIRECTORY SOURCE...
常用选项: 
-i: 交互式
-f: 强制

mv操作时,具体的流程是:

如果mv命令的目标和源在相同的文件系统,作为mv 命令
用新的文件名创建对应新的目录项,删除旧目录条目对应的旧的文件名,不影响inode(除时间戳)或磁盘上的数据位置:没有数据被移动!

如果目标和源在一个不同的文件系统, mv相当于cp和rm。

14. 删除

rm [OPTION]... FILE...

常用选项:

  • -i: 交互式
  • -f: 强制删除
  • -r: 递归
  • –no-preserve-root : 强制删除/目录,忽略root
    示例:
    rm -rf /

rm操作时候,具体的逻辑是:

  • 链接数递减,从而释放的inode号可以被重用
  • 把数据块放在空闲列表中
  • 删除目录项
  • 数据实际上不会马上被删除,但当另一个文件使用数据块时将被覆盖。
15. 目录操作

tree 显示目录树

  • -d: 只显示类型为目录
  • -L level:指定显示的层级数目
  • -P :pattern 只显示由指定pattern匹配到的路径
    1
    2
    3
    [root@localhost ~]# tree -P *Base* /etc/yum.repos.d/
    /etc/yum.repos.d/
    └── CentOS-Base.repo

mkdir 创建目录

  • -p: 存在时不报错,且可自动创建所需的各目录
  • -v: 显示详细信息
  • -m MODE: 创建目录时直接指定权限
    1
    2
    3
    [root@localhost ~]# mkdir -p -v -m 777 /tmp/c
    mkdir: created directory `/tmp/c'
    [root@localhost ~]#

rmdir 删除空目录

  • -p: 递归删除父空目录
  • -v: 显示详细信息
  • rm -r 递归删除目录树
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@localhost ~]# mkdir -p -v /tmp/x/y/z
    mkdir: created directory `/tmp/x'
    mkdir: created directory `/tmp/x/y'
    mkdir: created directory `/tmp/x/y/z'
    [root@localhost ~]# rmdir -p -v /tmp/x/y/z
    rmdir: removing directory, `/tmp/x/y/z'
    rmdir: removing directory, `/tmp/x/y'
    rmdir: removing directory, `/tmp/x'
    rmdir: removing directory, `/tmp'
    rmdir: failed to remove directory `/tmp': Directory not empty
16. 索引节点

inode(index node)表中包含文件系统所有文件列表
一个节点 (索引节点)是在一个表项(inode table),包含有关文件的信息( 元数据 包括:

  • 文件类型,权限,UID,GID
  • 链接数(指向这个文件名路径名称个数)
  • 该文件的大小和不同的时间戳
  • 指向磁盘上文件的数据块指针
  • 有关文件的其他数据

inode结构表

inode存值形式

根据inode找文件步骤

文件引用一个是 inode号

人是通过文件名来引用一个文件

一个目录是目录下的文件名和文件inode号之间的映射

17. 硬链接和软链接

详细说明[https://www.ibm.com/developerworks/cn/linux/l-cn-hardandsymb-links/inde.html#listing1(https://www.ibm.com/developerworks/cn/linux/l-cn-hardandsymb-links/inde.html#listing1 “转载自IBM博客”)

1. 硬链接

  • 创建硬链接会增加额外的记录项以引用文件
  • 对应于同一文件系统上一个物理文件
  • 每个目录引用相同的inode号
  • 创建时链接数递增
  • 删除文件时:
    • rm命令递减计数的链接
    • 文件要存在,至少有一个链接数
    • 当链接数为零时,该文件被删除
  • 不能跨越驱动器或分区
  • 语法: ln filename [linkname ]

    注意: 目录不能使用硬链接

2. 软链接

  • 一个符号链接指向另一个文件
  • ls - l的 显示链接的名称和引用的文件
  • 一个符号链接的内容是它引用文件的名称
  • 可以对目录进行
  • 可以跨分区
  • 指向的是另一个文件的路径;其大小为指向的路径字符串的长度;不增 - 加或减目标文件inode的引用计数;
  • 语法:ln -s filename ​​[linkname]

    注意:加粗部分为硬链接和软链接的核心区别。

18. 确定文件内容

文件可以包含多种类型的数据
检查文件的类型,然后确定适当的打开命令或应用程序使用

语法:file [options] <filename>...

常用选项:

  • -b 列出文件辨识结果时,不显示文件名称
  • -f filelist 列出文件filelist中文件名的文件类型
  • -F 使用指定分隔符号替换输出文件名后默认的”:”分隔符
  • -L 查看对应软链接对应文件的文件类型
  • –help 显示命令在线帮助
19. 标准输入与输出
  • 程序:指令+数据

    • 读入数据:Input
    • 输出数据:Output
  • 打开的文件都有一个fd: file descriptor (文件描述符)

  • Linux给程序提供三种I/O设备

    • 标准输入(STDIN)-0 默认接受来自键盘的输入
    • 标准输出(STDOUT)-1 默认输出到终端窗口
    • 标准错误(STDERR)-2 默认输出到终端窗口
  • I/O重定向:改变默认位置

  • 输入重定向:

    1
    2
    3
    4
    5
    [root@localhost ~]# cat > /tmp/luoq.txt <<EOF
    > woshishui
    > EOF
    [root@localhost ~]# cat /tmp/luoq.txt
    woshishui
20. 把输出和错误重新定向到文件
  • STDOUT和STDERR可以被重定向到文件
  • 命令 操作符号 文件名
  • 支持的操作符号包括:
    • >  把STDOUT重定向到文件
    • 2> 把STDERR重定向到文件
    • &> 把所有输出重定向到文件
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      [root@localhost ~]# touch /tmp/error.txt;cat /tmp/luo.txt1 2>/tmp/error.txt
      [root@localhost ~]# cat /tmp/error.txt
      cat: /tmp/luo.txt1: No such file or directory
      [root@localhost ~]#
      [root@localhost ~]# cat /tmp/luoq.txt &> /tmp/error.txt
      [root@localhost ~]# cat /tmp/error.txt
      woshishui
      [root@localhost ~]# cat /tmp/luoq.txt11 &> /tmp/error.txt
      [root@localhost ~]# cat /tmp/error.txt
      cat: /tmp/luoq.txt11: No such file or directory
  • > 文件内容会被覆盖
    • set –C 禁止将内容覆盖已有文件,但可追加
    • >| file 强制覆盖
    • set +C 允许覆盖
  • >> 原有内容基础上,追加内容
  • 2> 覆盖重定向错误输出数据流
  • 2>> 追加重定向错误输出数据流
  • 标准输出和错误输出各自定向至不同位置 COMMAND > /path/to/file.out 2>/path/to/error.out
  • 合并标准输出和错误输出为同一个数据流进行重定向
    • &> 覆盖重定向
    • &>> 追加重定向
    • COMMAND > /path/to/file.out 2>&1 (顺序很重要)
    • COMMAND >> /path/to/file.out 2>&1
    •  ():合并多个程序的STDOUT
    • ( cal 2007 ; cal 2008 ) > all.
      
21. tr命令

tr 转换和删除字符

  • 语法:tr [OPTION]... SET1 [SET2]
  • 选项:
    • -c –C –complement:取字符集的补集
    • -d –delete:删除所有属于第一字符集的字符
    • -s –squeeze-repeats:把连续重复的字符以单独一个字符表示
    • -t –truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符
    • [:alnum:]:字母和数字 [:alpha:]:字母 [:cntrl:]:控制(非打印)字符 [:digit:]:数字 [:graph:]:图形字符 [:lower:]:小写字母 [:print:]:可打印字符 [:punct:]:标点符号 [:space:]:空白字符 [:upper:]:大写字母 [:xdigit:]:十六进制字符

      例如:tr ‘a-z’   ‘A-Z’< /etc/issue

22. 管道
  • 管道(使用符号“|”表示)用来连接命令

  • 命令1 | 命令2 | 命令3 | …

    • 将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT送到命令3的STDIN
    • STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现
    • 最后一个命令会在当前shell进程的子shell进程中执行来
    • 组合多种工具的功能
    • ls | tr ‘a-z’ ‘A-Z’
  • 有些命令不支持管道传输过来的数据,可以加上 - 执行

23. tee命令,一路输入两路输出
  • 命令1 | tee [-a ] 文件名 | 命令2
    • 把命令1的STDOUT保存在文件中,做为命令2的输入
    • -a 追加
  • 使用:
    • 保存不同阶段的输出
    • 复杂管道的故障排除
    • 同时查看和记录输出

      例如:[root@localhost ~]# cat /etc/passwd | tr -d 'abc' | tr 'd-z' 'D-Z' | tee /tmp/luo.txt

24. selinux:安全Linux策略
  • 配置文件在/etc/selinux/config :
  • 查看状态的命令:getenforce
    • 三种状态:
      • enforcing:强制:违反规则不能运行
      • permissive许可:可以允许运行,但是会记录,用来后期的审计
      • disabled:禁用:关闭selinux
25. 历史命令:history的环境变量配置:

HISTCONTROL

  • -ignoredups(忽略重复)
  • -ignorespace(忽略空格)
  • -ignoreboth(忽略所有)
26.权限

认证;授权:审计 Authentication;Authorization;Adition

umask总结

umask:反向掩码

  • umask值 可以用来保留在创建文件权限
  • 新建FILE权限: 666-umask
    • 如果所得结果某位存在执行(奇数)权限,则将其权限+1
  • 新建DIR权限: 777-umask
  • 非特权用户umask是 002
  • root的umask 是 022
  • umask: 查看
  • umask #: 设定
    • umask 002
  • umask –S 模式方式显示
  • umask –p 输出可被调用
  • 全局设置: /etc/bashrc 用户设置:~/.bashrc

Linux基础-权限管理

一.权限管理

1.用户权限:

认证:1.1 Authentication;授权:Authorization;审计:Adition

1.2 Linux用户和组的主要配置文件:

  • /etc/passwd:用户及其属性信息(名称、UID、主组ID等)
  • /etc/group:组及其属性信息
  • /etc/shadow:用户密码及其相关属性
  • /etc/gshadow:组密码及其相关属性

1.3 安全上下文:进程代表用户在进行:谁启动了进程,进程就拥有谁的身份(以进程(process)发起者的身份运行)。

  • root:/bin/cat
  • mage:/bin/cat

1.4 用户

1.4.1 用户User:
  • 令牌token,identity
  • Linux用户:Username/UID
  • 用户级别:
    • 管理员:root, 0
    • 普通用户:1-65535
      • 系统用户:1-499, 1-999 (CentOS7)
        • 对守护进程获取资源进行权限分配
      • 登录用户:500+, 1000+(CentOS7)
        • 交互式登录
1.4.2 passwd文件格式:
  • login name:登录用名(wang)

  • passwd:密码 (x)

  • UID:用户身份编号 (1000)

  • GID:登录默认所在组编号 (1000)

  • GECOS:用户全名或注释

  • home directory:用户主目录 (/home/wang)

  • shell:用户默认使用shell (/bin/bash)

    1
    2
    3
    tcpdump:x:72:72::/:/sbin/nologin
    vampire:x:500:500:vampire:/home/vampire:/bin/bash
    mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false
    1.4.3 shadow文件格式:
  • 登录用名

  • 用户密码:一般用sha512加密

  • 从1970年1月1日起到密码最近一次被更改的时间

  • 密码再过几天可以被变更(0表示随时可被变更)

  • 密码再过几天必须被变更(99999表示永不过期)

  • 密码过期前几天系统提醒用户(默认为一周)

  • 密码过期几天后帐号会被锁定

  • 从1970年1月1日算起,多少天后帐号失效

    1
    2
    3
    tcpdump:!!:17735::::::
    vampire:$6$yk7XOpZX0ZngOz6D$qVI/.Q7Ch7M.KRfjsPC. WTiN9w2qJgUofENaFlnLxXpvzIN/lICVwcIme1b3LHMixqXxnEIGkgepuUIpsoadU1:1773 5:0:99999:7:::
    mysql:!!:17737::::::
1.4.4 用户创建

语法:useradd [options] LOGIN

  • -u UID

  • -o 配合-u 选项,不检查UID的唯一性

  • -g GID:指明用户所属基本组,可为组名,也可以GID

  • -c “COMMENT”:用户的注释信息

  • -d HOME_DIR: 以指定的路径(不存在)为家目录

  • -s SHELL: 指明用户的默认shell程序
    ​ 可用列表在/etc/shells文件中

  • -G GROUP1[,GROUP2,…]:为用户指明附加组,组须事先存在

  • -N 不创建私用组做主组,使用users组做主组

  • -r: 创建系统用户 CentOS 6: ID<500,CentOS 7: ID<1000

  • -m 创建家目录,用于系统用户

  • -M 不创建家目录,用于非系统用户

    1
    2
    3
    [root@localhost ~]# useradd -u 111 luoqian  -c "vamp" -s /bin/csh -m
    [root@localhost ~]# tail -1 /etc/passwd
    luoqian:x:111:501:vamp:/home/luqoian:/bin/csh
1.4.5 用户属性的修改:

语法:`usermod [OPTION] login

  • -u UID: 新UID
  • -g GID: 新主组
  • -G GROUP1[,GROUP2,…[,GROUPN]]]:新附加组,原来的附加组将会被覆盖;若保留原有,则要同时使用-a选项
  • -s SHELL:新的默认SHELL
  • -c ‘COMMENT’:新的注释信息
  • -d HOME: 新家目录不会自动创建;若要创建新家目录并移动原家数据,同时使用-m选项
  • -l login_name: 新的名字;
  • -L: lock指定用户,在/etc/shadow 密码栏的增加 !
  • -U: unlock指定用户,将 /etc/shadow 密码栏的 ! 拿掉
  • -e YYYY-MM-DD: 指明用户账号过期日期
  • -f INACTIVE: 设定非活动期限
1.4.6 删除用户:

语法:userdel [OPTION]... login

  • -r: 删除用户家目录
1.4.7 切换用户或以其他用户身份执行命令

语法:su [options...] [-] [user [args...]]

  • 切换用户的方式:
    • su UserName:非登录式切换,即不会读取目标用户的配置文件,不改变当前工作目录
    • su - UserName:登录式切换,会读取目标用户的配置文件,切换至家目录,完全切换
  • root su至其他用户无须密码;非root用户切换时需要密码
  • 换个身份执行命令:
    su [-] UserName -c 'COMMAND'
  • 选项:-l --login
    su -l UserName 相当于 su - UserName
1.4.8 修改密码

语法:passwd [OPTIONS] UserName: 修改指定用户的密码

  • 常用选项:
    • -d:删除指定用户密码
    • -l:锁定指定用户
    • -u:解锁指定用户
    • -e:强制用户下次登录修改密码
    • -f: 强制操作
    • -n mindays: 指定最短使用期限
    • -x maxdays:最大使用期限
    • -w warndays:提前多少天开始警告
    • -i inactivedays:非活动期限
    • –stdin:从标准输入接收用户密码
      echo “PASSWORD” | passwd –stdin USERNAME

1.5 组

1.5.1 Linux组的类别
  • 用户的主要组(primary group)
    • 用户必须属于一个且只有一个主组
    • 组名同用户名,且仅包含一个用户,私有组
  • 用户的附加组(supplementary group)
    • 一个用户可以属于零个或多个附加组
1.5.2 组group:
  • Linux组:Groupname/GID
  • 管理员组:root, 0
  • 普通组:
    • 系统组:1-499, 1-999(CENTOS7)
    • 普通组:500+, 1000+(CENTOS7)
1.5.3 group文件格式
  • 群组名称:就是群组名称
  • 群组密码:通常不需要设定,密码是被记录在 /etc/gshadow
  • GID:就是群组的 ID
  • 以当前组为附加组的用户列表(分隔符为逗号)
    1
    2
    3
    4
    [root@localhost ~]# cat /etc/group
    root:x:0:
    bin:x:1:bin,daemon
    daemon:x:2:bin,daemon
1.5.4 gshadow文件格式
  • 群组名称:就是群组名称
  • 群组密码:
  • 组管理员列表:组管理员的列表,更改组密码和成员
  • 以当前组为附加组的用户列表:(分隔符为逗号)
    1
    2
    3
    4
    5
    6
    [root@localhost ~]# cat /etc/gshadow
    root:::
    bin:::bin,daemon
    daemon:::bin,daemon
    sys:::bin,adm

1.5.5 创建组:

语法:groupadd [OPTION]... group_name

  • -g GID: 指明GID号;[GID_MIN, GID_MAX]
  • -r: 创建系统组
    • CentOS 6: ID<500
    • CentOS 7: ID<1000
1.5.6 修改和删除组:
  • 组属性修改:groupmod
    语法:groupmod [OPTION]… group

    1
    2
    -n group_name: 新名字
    -g GID: 新的GID
  • 组删除:groupdel
    groupdel GROUP

1.5.7 更改组密码
1
2
3
4
5
6
7
组密码:gpasswd
gpasswd [OPTION] GROUP
-a user 将user添加至指定组中
-d user 从指定组中移除用户user
-A user1,user2,... 设置有管理权限的用户列表
newgrp命令:临时切换主组
如果用户本不属于此组,则需要组密码

2 文件权限:

2.1 文件的权限主要针对三类对进行定义
  • owner: 属主, u,文档所有者
  • group: 属组, g,文档所属组用户
  • other: 其他, o,其他用户
  • 每个文件针对每类访问者都义了三种权限
    • r: Readable:读
    • w: Writable:写
    • x: eXcutable:执行
2.2 文件和目录权限的区别:
  • 文件:
    • r: 可使用文件查看类工具获取其内容
    • w: 可修改其内容
    • x: 可以把此文件提请内核启动为一个进程
  • 目录:
    • r: 可以使用ls查看此目录中文件列表
    • w: 可在此目录中创建文件,也可删除此目录中的文件
    • x: 可以使用ls -l查看此目录中文件列表,可以cd进入此目录
2.3 修改文件权限:
1
2
3
4
5
6
7
8
9
10
chmod [OPTION]... OCTAL-MODE FILE...
-R: 递归修改权限(改目录的时候想修改目录内部所有文件的权限,但是不建议)
chmod [OPTION]... MODE[,MODE]... FILE...
MODE:
修改一类用户的所有权限:
u= g= o= ug= a= u=,g=
修改一类用户某位或某些位权限
u+ u- g+ g- o+ o- a+ a- + -
chmod [OPTION]... --reference=RFILE FILE...
(referance)参考RFILE文件的权限,将FILE的修改为同RFILE
2.4 修改文件的属组和属主:
  • 修改文件的属主:chown
    • chown [OPTION]… [OWNER][:[GROUP]] FILE…
    • 用法:
      • OWNER
      • OWNER:GROUP
      • :GROUP
      • 命令中的冒号可用.替换
      • -R: 递归
  • 语法:-chown [OPTION]... --reference=RFILE FILE...
  • 修改文件的属组:chgrp
    1
    2
    3
    chgrp [OPTION]... GROUP FILE...
    chgrp [OPTION]... --reference=RFILE FILE...
    -R 递归

注意:
- (权限一定要给全,不然会从左边补全,例如如果给77,则默认为077)
- (目录一定要有执行权限,普通文件不能随便给执行权限(防止一些恶意文件留后门)),
- (只写+w,只有属主加写权限)

2.5 新建文件和目录的默认权限
  • umask值 可以用来保留在创建文件权限
  • 新建FILE权限: 666-umask
    • 如果所得结果某位存在执行(奇数)权限,则将其权限+1
      新建DIR权限: 777-umask
  • 非特权用户umask是 002
  • root的umask 是 022
  • umask: 查看
  • umask #: 设定
    • umask 002
  • umask –S 模式方式显示
  • umask –p 输出可被调用
  • 全局设置: /etc/bashrc 用户设置:~/.bashrc
2.6 访问控制列表
  • ACL:Access Control List,实现灵活的权限管理

  • 除了文件的所有者,所属组和其它人,可以对更多的用户设置权限

  • CentOS7 默认创建的xfs和ext4文件系统具有ACL功能

  • CentOS7 之前版本,默认手工创建的ext4文件系统无ACL功能,需手动增加

    • tune2fs –o acl /dev/sdb1
    • mount –o acl /dev/sdb1 /mnt/test
  • ACL生效顺序:所有者,自定义用户,自定义组,其他人

  • 为多用户或者组的文件和目录赋予访问权限rwx

    • mount -o acl /directory
    • getfacl file |directory
    • setfacl -m u:wang:rwx file|directory
    • setfacl -Rm g:sales:rwX directory
    • setfacl -M file.acl file|directory
    • setfacl -m g:salesgroup:rw file| directory
    • setfacl -m d:u:wang:rx directory
    • setfacl -x u:wang file |directory
    • setfacl -X file.acl directory
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      [root@localhost ~]# getfacl linux222.txt
      # file: linux222.txt
      # owner: root
      # group: root
      user::rw-
      group::r--
      other::r--

      [root@localhost ~]# setfacl -m u:vampire:wx linux222.txt
      [root@localhost ~]# getfacl linux222.txt
      # file: linux222.txt
      # owner: root
      # group: root
      user::rw-
      user:vampire:-wx
      group::r--
      mask::rwx
      other::r--