--
权限(mode,permission)
权限的判断为:一个用户(非一个程序)对一个文件拥有什么样的权限
-rw------- 1 root root 1112 Mar 27 03:14 anaconda-ks.cfg
rw------- 权限用九位来表示
前三位代表用户(u表示),中间三位代表组(g表示),后三位代表others(o表示)
权限有三种 r (read) 读 w (write) 写 x (execute) 执行
a表示all a=u+g+o
r 读 权限
针对目录,有r权限,就代表能对此目录有列表的功能 (就是ls列出来的功能)
针对文件,有r权限,就代表能对此文件有阅读的功能 (就是指cat一类的命令)
w 写 权限
针对目录,有w权限,就代表在此目录下创建(删除)文件或者子目录 (touch,mkdir等)
针对文件,有w权限,就代表能在此文件写入内容或者修改 (> ,>>, vi 再写等)
x 执行 权限
针对目录,有x权限,就代表能进入此目录 (cd)
针对文件,有x权限,就代表能执行它 (命令,可执行文件等)
1,创建一个文件test,要求它实现user1只读,user2,user3可读可写,user4,user5可读可执行
先把user2,user3加入到group1组,然后创建下面的一个文件
r--rw-r-x user1 group1 test
2,创建一个文件test,要求它实现user1只读,user2,user3可读可写,user4,user5可读可执行,user6,user7可读可写可执行,user8,user9对其没有任何权限
这样的需求,仅靠九位权限实现不了;一定要实现,可以用文件file acl来做(主要的命令为setfacl和getfacl)
权限的修改
# chmod a+x 1.txt
# chmod g+x 1.txt
# chmod a+x 1.txt
# chmod a-r 1.txt
chmod u-w,g+x,o+x 1.txt --也可以一次性连写
权限用数字来表示 (r,w,x都可以用数字来表示)
r 4
w 2
x 1
rwx 7
rw_ 6
r_x 5
r__ 4
_wx 3
_w_ 2
__x 1
___ 0
-rw-r--r-- 这个以数字表示为644(严谨的说,不能叫它六百四十四,要叫它六四四)
每三位里r代表4,w代表2,x代表1;由三个数组成一个三位数,就是你的权限
# chmod 755 1.txt
# chmod 644 1.txt
chown user1.user1 1.txt --这个是改owner和group属性的
chown user1:user1 1.txt
什么情况下才能删除一个文件或目录?
答:跟这个文件或目录本身的权限无关,跟你对它们的上一级目录是否有写权限有关。你对一个目录有写权限,你就可以删除这个目录里任何文件
请问下面的情况,我一个普通用户能否rm -rf /test/abc/删除这个子目录
# ll -d /test
drwxr-xrwx. 3 root root 12288 Jul 16 17:42 /test
# ll /test
drwxr-xr-x. 2 root root 4096 Jul 16 17:40 abc
# ll /test/abc/
-rw-r--r--. 1 root root 0 Jul 16 17:40 1.txt
答案:删除不了,因为如果abc是个空目录就可以,但因为删除不了abc下的1.txt这个文件,所以造成abc也删除不了
什么情况下修改了一个文件才需要强制保存,什么情况下能够成功强制保存?
答案:如果你对一个文件没有写权限,那么修改后,要保存就会出现强制保存的选项;
虽然你对这个文件没有写权限,但如果你对文件所在的上一级目录有写权限,则可以强制保存成功,并且保存后,把文件的owner和group属性改成了你自己
如果对上一级目录没有写权限,则不可以强制保存;但也有一个例外,就是如果这个文件的owner就是你,那么你对它没有写权限,对它上级目录也没写权限,也可以强制保存成功
如果文件有i属性,那么无论什么情况都不能强制保存
如果一个用户对一个目录有r没有x会怎么样?有x没有r会怎么样?
这两种情况都是错误的情况,一般对目录要么能r能x,要么就都不行.
====================================================================================
特殊权限位(s,t)
s位叫特权位,英文的叫法有setuid,setgid,suid,sgid等
特权位s
一个可执行文件拥有s位时,当其它用户来执行这个可执行文件的话,使用的权限是此可执行文件属主或者属组的权限
只针对前三位,中间三位
对目录可以加,但是无效,因为目录不是命令,根本不能执行它
[root@li ~]# ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 30768 Feb 17 2012 /usr/bin/passwd
[root@li ~]# ll /etc/shadow
----------. 1 root root 1434 Jul 17 09:27 /etc/shadow
--普通用户修改密码使用passwd能改自己的密码,但是密码是存放在/etc/shadow里,也就是说普通用户对/etc/shadow没有写的权限,但passwd可执行文件的前三位有s位,所以普通在调用passswd时是用的root的权限
小实验:
1,测试passwd命令的s位,去掉其s位,普通用户就不能自己改自己密码了,加上s位就可以了
2,/bin/touch这个命令是没有s位的,你可以尝试加上s位,然后用普通用户touch文件,观察效果。做完测试后,记得改回来也就是把s位去掉
3,普通用户能关机吗?怎么让普通用户关机
可以对关机命令加s位来让普通用户能关机,在rhel6下测试reboot,shutdown可以这样做,init不能这样做
这只是一个理论讨论,实际情况不会这么做的
--生产环境很多root的事情给普通用户做,是使用sudo工具来授权
===================================================================================
粘贴位t --只针对目录有效
特别用在/tmp目录
有t位的目录,任何用户在有权限的情况下是可以创建文件和目录,就算是有权限删除别人的文件或目录也不能删除
自己只能删除自己创建的目录,用于一些共享上传的文件服务器场合
会提示Operation not permitted --这是操作不允许,不是pemission denied
小实验:
用一个测试目录(比如:/test/),再用两个普通用户,分别在此目录里建立不同的文件
测试结果:
目录没有t位,只要能写,能删除里面的任何文件
有t位,只能删除自己的文件
s位和t位注意的地方:
用数字表示
前三位上加s 4
中间三位加s 2
后三位加t 1
chmod 1777 /tmp --/tmp目录的t位很重要,不要把它去掉,否则会影响很多程序的运行
s位和t位大小写的区别
小写的话就表示 有x执行权限
大写的话就表示 没有x执行权限
======================================================================================
文件属性 (file attributes)
lsattr
chattr
介绍几个常见重要的属性:
属性1: A
# lsattr 1.txt
-------------e- 1.txt
# chattr +A 1.txt --这个属性让文件的access time访问后也不会变化,节省了IO(IO优化);默认情况下rhel5,访问一次atime就会跟着变一次,rhel6下只有当atime等于或早于mtime和ctime之一时,才会访问跟着变,否则不会变。(原因我们在后面讲mount参数时再补充)
# lsattr 1.txt
-------A-----e- 1.txt
# stat 1.txt |tail -3 --用cat命令访问这个文件,再用此命令查看access time,会发现不再变化
Access: 2014-07-17 11:12:58.589838878 +0800
Modify: 2014-07-17 11:12:58.589838878 +0800
Change: 2014-07-17 11:13:15.405701371 +0800
属性2: a
一个文件加了a属性,重定向覆盖以前的内容不允许,但追加内容是可以的(可用于比如日志文件的场景)
# lsattr 1.txt
-----a-------e- 1.txt
# echo 456 > 1.txt
bash: 1.txt: Operation not permitted
# echo 456 >> 1.txt
属性3: i
# chattr -a 1.txt
# chattr +i 1.txt --加了i属性,此文件不可被修改,不能重命名,不能删除,不能改变内容
总结:文件的权限(mode,permission)为r,w,x,s,t;文件的属性(attributes)为A,a,i等;以后学的selinux就类似在这些权限和属性的基础上再做扩展
==================================================================================
环境变量
env --看环境变量
set --除了环境变量,还能看自定义变量
[root@li ~]# abc="hello world"
[root@li ~]# env | grep abc
[root@li ~]# set | grep abc --set可以查出这个自定义变量
abc='hello world'
# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/root/bin
# echo $USER
root
# echo $HOME
/root
# echo $RANDOM --产生一个随机数,范围大概是0-32768
# echo $PS1 --这是终端前的命令提示符
[\u@\h \W]\$
小实验1:
# PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/root/bin --在原来的基础上,去掉/bin目录
# ls --ls命令虽然还在/bin目录下,但是不能直接使用了,需要绝对路径才能使用
bash: ls: command not found
测试完后,还原
小实验2:
[root@li test]# PS1="@_@: " --修改终端提示符
@_@: pwd --然后就会发现提示符变成了自己指定的了
/test
@_@: PS1='[\u@\h \W]\$ ' --还原
[root@li test]# --还原后的提示符
--上面的实验做的变量都不是永久的,也就是说重启终端或系统后就不生效了
用户的环境变量设定文件,在每个用户的家目录里都会有下面四个文件
.bash_logout --用户登出后执行的 可以在这里加上清除.bash_history的命令,在用户登出时清掉之前的操作
.bash_history --用户的历史命令存放的地方 用history命令可以查看,它不记录当前会话用过的命令,当你退出时,它才会记录你退出前所操作的命令
.bash_profile --用户的环境变量设定的地方 用户登录时执行
.bashrc --别名设定的文件 用户登录时执行
系统默认在root用户家目录里的.bashrc里设定了以下几个别名
# vim /root/.bashrc
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i' --这三个命令都已经做了-i参数的别名,是系统为了安全性防止用户误操作设定的
系统全局环境变量文件
/etc/bashrc /etc/profile --这两个文件是对所有用户都生效,全局性的
例1:为了安全性考虑,我希望我对一个用户操作的命令不能被别人查到
# vim /home/abc/.bash_logout
history -c --加这一句表示把当前会话的所有命令记录清空
rm -rf .bash_history --把此文件删掉,也就表示不会有以前的命令记录
扩展:假设你的上级要求你每天把你操作的命令在下班后以邮件的形式发给他,而且还要考虑到安全,操作后命令记录要被清空
# vim /home/abc/.bash_profile
logintime=`date +%T` --加上这句,记录登录的时间
# vim /home/abc/.bash_logout
clear
history -w
echo "开始时间为$logintime" >> history_record_today.txt
cat .bash_history >> history_record_today.txt
echo -e "结束时间为`date +%T`\n" >> history_record_today.txt
history -c
rm -rf .bash_history
把下面两句写一个脚本,然后用时间任务在下班后的一个时间点定时去做就可以了
mail -s "`date +%F` record from zhangsan" boss@xxxx.com < history_record_today.txt
rm -rf history_record_today.txt
2,实现用户一登录,我就用一个文本来记录什么用户什么时间登录的
格式如: user1 2017-07-23 18:00:00
# touch /tmp/login
# chmod 777 /tmp/login
# vim /etc/profile --在此文件最后加上下面一句
echo -e "$USER\t`date +'%F %T'`" >> /tmp/login --e参数是表示里面\t转义为制表符,\n转义为回车换行
# source /etc/profile
# . /etc/profile --这两条是让你修改过的环境变量文件生效,rhel5需要做,现在rhel6可以不用做这一步
3,实现root用户密码的自动更改(一般来说,这种需求是用时间任务去做的);这里我要求是用户一登录,密码就变了,也就是说下一次登录的密码不一样了。密码随意。(最好用虚拟机来测试)
密码修改提示: echo 123 | passwd --stdin root &> /dev/null
# vim /root/.bash_profile
echo "helloworld`date +%Y%m%d`" | passwd --stdin root &> /dev/null
或者
echo "helloworld$RANDOM" | passwd --stdin root &> /dev/null
--密码你可以改完后,把它用重定向的方法重定向到一个文件保存下来
4,实现一个普通用户登出时,显示登录了多久
如abc用户登出时,会自动显示"你好,abc,你一共登录了xx时xx分xx秒,bye bye"
提示: 两个变量的相减运算$[$a-$b]
# vim /home/abc/.bash_profile
logintime=`date +%s`
# vim /home/abc/.bash_logout
clear
logouttime=`date +%s`
alltime=$[$logouttime-$logintime]
hours=$[$alltime/3600]
minutes=$[$alltime%3600/60]
seconds=$[$alltime%60]
echo "你好,$USER,你一登录$hours时$minutes分$seconds秒,bye bye"
上面这个做法只针对了一个用户,如果我现在有很多用户,都要做这个,如何实现?
第一种,把上面写成shell脚本循环执行
第二种,
先说一下useradd abc这条命令到处执行了哪些步骤
useradd abc 的七步:
一。 /etc/passwd 加上abc:x:532:533::/home/abc:/bin/bash
二。 /etc/shadow 加上abc:!!:14709:0:99999:7::: --密码可以用grub-md5-crypt 命令建立
三。 /etc/group 加上abc:!!:14709:0:99999:7:::
四。 /etc/gshadow 加上abc:!::
五。 mkdir /home/abc --建立家目录 手动建立后注意属主和属组
六 touch /var/spool/mail/abc --建立用户的存放邮件的文件 手动建立后注意属主和属组
七。 cp /etc/skel/.bash* /home/abc/ --拷环境变量模版到用户家目录
ls /etc/skel/ -a
.bash_logout .bash_profile .bashrc
通过讲了useradd abc的步骤,第二种方法就可以想到了,就是把上面的做法写到/etc/skel/.bash_profile和/etc/skel/.bash_logout里.然后建立任何用户都会拷贝这些已经修改好的。但这种方法比较适合用户都还没有建立的情况,第一方法就无所谓。
5,实现一个普通用户30秒不操作则自动退出
在用户的家目录里的.bash_profile里加上下面一句
TMOUT=30