本节主要讲述了文件的权限管理,bash的编程环境和变量和配置文件,以及几个文本处理的命令和程序控制结构
对文件访问常用的权限有三种,分别是读,写,执行,简写为r,w,x
文件读(r)权限可以使用内容查看类的命令来显示相关内容
文件写(w)权限可以使用编辑器或者重定向来修改其内容
文件执行(x)权限可以将其发起一个进程
对于目录而言,读权限可以使用ls命令查看目录内容的文件信息;写权限可以在目录中创建和删除文件;执行权限可以使用ls -l命令查看目录内容的文件信息,并且可以使用cd命令切换至此目录为工作目录
文件权限有九位,每三个一组,分为用户权限组权限和其他用户的权限,当用户不拥有某位权限,使用-占位
每一位只有两种变化,有或者没有,可以使用二进制表示,三位二进制可以用一位八进制数字
000:---:0
001:--x:1
010:-w-:2
011:-wx:3
100:r--:4
101:r-x:5
110:rw-:6
111:rwx:7
文件的权限是文件的元数据信息,元数据保存在inode中
修改文件的属主和属组只有管理员可移植性,常用的有chown和chgrp
更改文件权限使用chmod
文件权限的更改
修改权限有三种方法:
- 一次性修改三类用户的权限,使用八进制指定的形式
# chmod 754 file1
- 修改指定类别用户的权限,使用u,g,o,a来赋权,基于=或者+、-来进行
u表示属主,g表示属组,o表示其他用户,a表示所有,=操作指定类别用户的权限,+/-操作指定类别用户的单个权限
# chmod u=rx File1
# chmod u=rwx,g=rx,o= File1
# chmod u+x,o-x,+x File1 直接加或者减代表所有的用户增加或者删除某权限
- 参照其他文件的权限为当前文件赋权
# chmod --reference=参考文件 File1
修改目录的权限并不会更改目录内的文件权限,使用-R选项递归更改目录内的所有文件,对链接文件无效
所有符号链接的权限都为777,因为权限控制在指向文件的权限控制
创建文件的默认权限
创建文件的默认权限是使用666-umask,创建目录的默认权限是使用777-umask
umask是遮罩码,文件默认决不允许出现执行权限,一旦出现执行权限,则在执行权限位上加一
使用umask 数值
就可以修改遮罩码,修改只对当前进程有效,如果要一直生效,则要写入配置文件
如果用户和基本组组名一致umask为002,否则为022
修改文件的属主和属组
支持-R递归选项和--reference
chown [option] Username file
chgrp [option] Groupname file
chown可以同时更改属主和属组 chown Username:Groupname file,也可以只更改属组 chown :Groupname file
属主和属组可以使用:或者.或者|分隔
权限应用模型
进程的属主,是否与文件的属主相同,如果相同,进程则以文件属主的的权限来访问文件;
否则进程的属主所属的组,是否其中之一与文件的属组相同;如果相同,进程则以文件的属组的权限来访问文件;
否则进程以文件的其他用户的权限来访问文件
bash的快捷键
快捷键组合 | 功能 |
---|---|
CTRL+a | 跳至命令行首 |
CTRL+e | 跳至命令行尾 |
CTRL+u | 删除命令行首至至当前光标所在处的内容 |
CTRL+k | 删除当前光标所在处至命令行尾的内容 |
CTRL+l | 清屏,相当于clear |
CTRL+c | 终止或者取消命令 |
CTRL+z | 将当前的命令送至后台,使用fg调回命令 |
bash的补全功能
bash支持命令补全和路径补全
命令补全可以在PATH中搜索并补全,使用tab补全,区分一次tab键和两次tab键,补全是从左至右查找
路径补全在给出的打头路径下补全,如果没有打头路径,则为当前目录
编程环境
bash支持变量,支持程序控制逻辑,任何一个需要执行的程序都需要一个解释器,bash没有解释器,实际上是调用已经编译好的二进制文件
一个程序在内存在内存中转换为一个进程,指令存在一段内存空间中,数据存放在变量中,
C语言是事先定义了一组规范,通过关键字按照特定的语法结构转换成汇编程序
编译器是翻译官是语言平台,解释器也是语言平台
程序执行逻辑通常有三种,顺序执行、选择(条件)执行和循环执行
编程语言的类型
大部分解释性语言都是动态语言,如per、bash、python
大部分的编译型语言都是静态语言,如C、C++
数据的存储格式
ASCII和Binary
数据的存储格式的不同占用的内存空间的大小也不相同
变量
变量需要事先声明的,是强类型的编程语言,反之是弱类型语言,C是典型的强类型语言,python也是强类型语言,bash是动态弱类型语言
弱类型语言不强制区分变量的类型,无论存储何种数据均视为字符格式;无需事前声明,直接赋值
定义变量类型的作用
数据存储格式
数据的有限存储范围
比较机制不同
参与的运算类型不同.
变量类型
变量类型两个大类是字符型和数值型,数值型有精确数值型(整形)和近似数值型(浮点数)
浮点数分为单精度浮点型和双精度浮点型
另外两种类型是时间日期型和布尔型
脚本执行格式
任何脚步语言执行都要指定解释器#!解释器路径
,要在脚本第一行的顶格显示
对于非二进制格式的脚本,linux在执行的时候,发现是脚本不遵循ELF规范,在脚本头不发现#!/bin/bash,内核停止执行脚本,转而打开解释器,由解释器逐条解释执行,这个 脚本的内容作为解释器的参数
变量的命名
只能使用数字、字母和下划线
不能以数字开头
不能使用程序的关键字
见名知意
bash中的变量类型有本地变量、局部变量、环境变量、位置变量、特殊变量
本地变量只对当前shell进程有效看,对其子shell及其其他shell都无效,使用set命令定义变量名称,[set] Var_name='value'
引用变量使用${Var_name},花括号可以省略;撤销变量使用unset Var_name
单独使用set命令显示当前进程的所有变量
局部变量只对脚本的一部分有效,使用local Var_name='value'
环境变量
环境变量当前shell及其子shell有效,使用export Var_name='value'定义环境变量,也可以使用Var_name='value‘;export Var_name将本地变量提升为环境变量
环境变量用来定义bash的工作特性,用于保存当前会话的属性信息
使用export命令可以显示所有环境变量,也可以使用env或printenv命令
修改环境变量的值export PATH=$PATH:/example
位置变量
位置变量可以引用脚本参数的变量,$1......$n
特殊变量
特殊变量有$0表示脚本名称自身;$?表示上一条命令的执行状态,返回值用数字表示,范围是0-255,0表示成功执行,1-255表示失败;还有一些特殊变量日后遇到在记忆即可
bash的配置文件可以持久的保存用户配置,bash的配置文件有两类,分别是profile类和bashrc类
配置文件在bash启动时被读取,而且只在bash第一次启动时读取一次,只有用户退出再重新登录才会读取,bash运行过冲中不会多次读取配置文件,除非手动读取(最好重新登录,使用souce命令可以手动读取,souce可以简写为.)
profile类
为交互式登录的用户提供配置(并非严格意义)
交互式登录指的是直接通过终端输入用户信息登录系统,su [-|-l] Username也属于交互式登录,交互式登录属于完整登录
/etc/profile 全局配置文件,基本配置
/etc/profile.d/*.sh 全局配置文件,各大部分的配置文件
用户家目录下的~/.bash_profile个人配置文件,仅对当前用户有效
profile类的配置文件的作用是设定环境变量;用来实现运行命令或脚本
bashrc类
为非交互式登录的用户提供配置(并非严格意义)
非交互式登录指的是通过图形界面的终端或者使用su Username登录的用户或者使用脚本登录的属于非交互式登录
/etc/bashrc 全局配置文件
~/.bashrc仅对指定用户生效
bashrc类的作用用来设定本地变量,可以定义命令别名
配置文件的读取顺序
如果配置有冲突,后读的配置文件生效
交互式登录用户
/etc/profile-->/etc/profile.d/*.sh-->/.bash_profile-->/.bashrc-->/etc/bashrc
非交互式登录用户
~/.bashrc-->/etc/bashrc-->/etc/profile.d/*.sh
在面向过程的编程语言中有三种执行顺序:
顺序执行:默认顺序执行,逐条执行各语句
选择执行:使用条件判断,符合条件的分支予以执行
循环执行:将同一段代码反复执行有限次,循环必须有退出条件,否则会陷入死循环
控制语句
bash的循环控制语句:for,while,until
for循环:通过使用一个变量去遍历给定列表中的每个元素,在每次赋值时执行一次循环体,直至赋值完成所有元素,退出循环
for 变量名 in 列表;do
循环体
done
bash -n 脚本文件
可以对脚本进行语法检查
列表的生成
生成数字序列:{start..end},seq [start] [step] end,当生成的数字序列有变量替换时,只能使用seq命令
直接给出列表
使用文件名通配机制生成的列表
使用命令生成
文本计数wc
wc [option] [file]
默认显示的是 行数 单词数 字节数
选项 | 作用 |
---|---|
-l | 统计行数 |
-c | 统计字节数 |
-w | 统计单词数 |
转换或删除字符tr
使用tr可以对字符进行转换或删除,需要使用管道
tr ‘集合一’ ‘集合二’
tr -d ‘集合’
字符转换会把第一个字符集对应转换为第二个字符集中相对应的字符,使用-d选项表示删除出现过的字符集
字符拆分cut
cut命令可以根据指定的分隔符,将整行切割为n个部分,显示指定的部分
-d指定字符:指定分隔符
-f数字:指定要显示的字段。单个数字表示一个字段,逗号分隔的多个数字,如1,3,5,多个连续字段使用-,如3-8
eg.cut -d: -f1,7 /etc/passwd
cut处理的缓冲区的文本,不会修改文件
字符排序sort
sort默认为升序排序,一般用法 sort [option] file
选项 | 作用 |
---|---|
-f | 忽略大小写 |
-n | 对数字进行排序 |
-t | 指定分隔符 |
-k 数字 | 指定分隔后进行比较字段 |
-u | 重复的行,只显示一行 |
移除重复行uniq
连续的相同行才称为重复行
选项 | 作用 |
---|---|
-c | 统计每一行出现的次数 |
-d | 仅显示出现至少两次的行 |
-u | 仅显示从未重复的行 |
1.新建一个用户openstack,但不给其创建家目录;创建完成后使用su命令切换至此用户,查看其命令提示符以及PATH和HOME两个环境变量;
2.复制/etc/skel目录为home/openstack;
3.改变/home/openstack以及其内部文件的属主属组均为openstack;
4./home/openstack以及其内部文件,属组和其他用户没有任何访问权限
# useradd -M openstack
# su - openstack
# echo $PATH $HOME
# su - root
# 密码
# cp -r /etc/skel /home/openstack
# chown -R openstack:openstack /home/openstack
# chmod -R go= /home/openstack
# su - openstack
# echo $PATH $HOME
1.新建系统组mysql;新建系统用户mysql,属于mysql组,要求其没有家目录且shell为sbin/nologin
# groupadd -r mysql
# useradd -r -s sbin/nologin -g mysql mysql
2.新建GID为600的组magedu;新建用户gentoo,要求其家目录为/users/gentoo,密码同用户名
# groupadd -g 600 magedu
# mkdir /users
# useradd -d /users/gentoo gentoo
# passwd gentoo
3.新建用户centos,其家目录为/users/centos,密码同用户名
# useradd -d /users/centos centos
# passwd centos
4.新建用户www,其家目录为/users/www,删除www用户,但保留其家目录
# useradd -d /users/www www
# userdel www
5.用户gentoo和centos均已magedu为其附加组
# usermod -Ga magedu gentoo
# usermod -Ga magedu centos
1.创建一个组 newgroup,id号为4000
2.创建一个用户magedu1,id号为3001,附加组为newgroup
3.创建目录/tmp/hellodirxyz
4.复制/etc/fatab至上面的目录中
5.改变目录及其内部文件的属主和属组为magedu1
6.让目录及内部文件的其他用户没有任何权限
#!/bin/bash
groupadd -g 4000 newgroup
useradd -u 3001 -G magedu1
mkdir /tmp/hellodirxyz
cp /etc/fstab /tmp/hellodirxyz
chown -R magedu1.magedu1 /tmp/hellodirxyz
chmod -R o= /tmp/hellodirxyz
#!/bin/bash
mygroup=‘newgroup’
myuser=simon
mydir=“/tmp/hellodirxyz”
myid=3001
useradd -g 4000 $mygroup
useradd -u $myid -G $mygroup $myuser
1.切换至centos用户,定义本地变量FirstVar,值为test variable
su - centos
set FirstVar=“test variable”
2.另启动 一个终端,使用gentoo用户查看FirstVar变量的值:如果没有值,为什么
没有值,本地变量只对当前shell有效
3.声明一个变量curtime,其值为当前系统时间
set curtime=‘date+%T’
4.使用echo命令显示:the current time is :is后面跟上curtime的值
echo “the current time is:$curtime”
5.返回值centos用户的终端:复制/etc/pam.d目录至/tmp目录中,并重命名为test
cp-r /etc/pam.d /tmp/test
6.声明变量filename ,其值为刚才复制的目录/tmp/test
filename=“/tmp/test”
7.修改变量filename所表示的目录以及其内部所有文件的其他用户均没有任何访问权限
chmod -R o= $filename
8.centos用户是否可以修改变量filename所表示的目录的属主和属组?如果能,将其改为gentoo用户和gentoo组,如果不能,则使用root用户修改
不能
chown -R gentoo:gentoo $filename
写一个脚本添加用户user101-110
#!/bin/bash
for username in seq 101 110;do
useradd user$username
echo "Add user$username successfully"
done
写一个脚本,用file命令显示/var/log目录下的每个文件类型。提示:列表生成的方法为/var/log/*
#!/bin/bash
dirName=/var/log
for fileName in $dirName/*;do
file $fileName
done
写一个脚本
创建/tmp/scripttest目录,用变量保存目录名
在目录里创建测试文件tfile1-tfile20
创建用户testuser1和testuser2
将tfile1-tfil10的属主和属组改为testuser1
将tfile11-tfil20的属主和属组改为testuser2
#!/bin/bash
dirname=/tmp/scripttest
mkdir $dirname
for fileNo in {1..20};do
touch $dirName/tfile$fileNo
echo -n "Create $dirName/tfile$fileNo finished"
done
user add testuser1
user add testuser2
for fileNo in {1..10};do
chown testuser1:testuser1 $dirName/tfile$fileNo
done
for fileNo in {11..20};do
chown testuser2:testuser2 $dirName/tfile$fileNo
done
1.统计/bin、/usr/bin /sbin 和/usr/sbin等各目录中的文件个数
ls /bin | wc -l
2.显示当前系统上所有用户的shell,要求每种shell只显示一次
cut -d: -f7 /etc/passwd | sort -u
3.取出/etc/passwd文件的第七行
head -7 /etc/passwd| tail -1
4.显示上一题中取出的第七行的用户名,并改成大写
head -7 /etc/passwd| tail -1|cut -d: -f1| tr ‘a-z’ ‘A-Z’
5.统计/etc目录下以p或者P开头的文件个数
ls -d /etc/[Pp]* | wc -l
写一个脚本,用for循环实现显示/etc/init.d/functions、/etc/rc.d/rc.sysinit 和/etc/fstab各有多少行
#!/bin/bash
for count in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab;do
echo "$count:wc -l $count | cut -d'' -f1 lines"
done
写一个脚本将上题中三个文件复制到/tmp目录中:
用for循环实现,分别将每个文件的最近一次修改时间改为2011年9月15号13点27分
#!/bin/bash
for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab;do
cp $fileName /tmp
touch -m -t 201109151327 /tmp/basename $fileName
done
写一个脚本显示/etc/passwd中第3、7和11个用户的用户名和ID号
#!/bin/bash
for a in 3 7 11;do
head -n $a /etc/passwd| tail -1 | cut -d: -f1,3
done