软件就有 i386, i686 及 x86_64 之分
*/--------一些工具指令-------------
cal */# 日历
cal 2009 */# 日历年 cal [month] [year]
cal 10 2009 */# 日历年月
cal 13 2009 */# 日历月份
bc */# 计算器+-*/
quit */# 退出
*/# [tab]键可做为命令补齐或档名补齐
*/# -------------说明命令的用途-------------------
man date */# 帮助提示 (man page 的数据放在/usr/share/man 修改/etc/man.config)
『/word』 */# 向『下』搜寻关键
『?word』 */# 向『上』搜寻
n,N */# 『反向』搜寻
q */# 退出
man 1 man */# 这里是用 man(1) 的文件数据
man 7 man */# 这里是用 man(7) 的文件数据 搜寻的顺序是记录在/etc/man.conf 这个配置文件当中
『man -f 指令』 */# 指令和档案的完整名称 相当于 『whatis』
『man -k 指令』 */# 只要有 man 这个关键词就将该说明列出来『apropos』
『info info 』 */# 类似man将文件数据拆成一个一个的段落,还有类似网页的『超链接』,每个页面也被称为一个节点(node)
*/# info指令的文件默认是放置在/usr/share/info/这个目录当中的, info page 的格式来写成在线帮助文件
*/#man:为 1) 一般用户可以使用的指令或可执行文件案 5)一些配置文件的档案内容格式 8)系统管理员能够使用的管理指令。
/etc/man.config */# 依据 MANPATH 的路径去分别搜寻,CentOS 用的是 /etc/man.config ,而 SuSE 用的则是/etc/manpath.config
grep --color=auto ‘MANPATH‘ /etc/man.config */# 取出 /etc/man.config 内含 MANPATH 的那几行
*/------------doc说明文档目录------------------
/usr/share/doc */# 这个目录下的数据主要是以套件(packages)为主
/usr/share/doc/gcc-xxx */# (表示GCC 这个套件, xxx 表示版本)
/usr/share/doc/centos-release-notes-5.3/ */# 这个目录是说明文件档
/usr/share/doc/bash-3.2/ */# bash 是什么
*/---------忘记 root 密码的解决办法-----------
系统重新启动,按下『e』进入grub开机管理程序的编辑模式,再按一次『 e 』进入 kernel 该行的编辑画面中
最后方输入 single :kernel /vmlinuz-2.6.18-128.el5 ro root=LABEL=/ rhgb quiet single
再按下『 Enter 』再按 b 就进入单人维护模式了,passwd输入两次新的密码
*/------------重新启动,关机: reboot, halt, poweroff -----------------
$ 与 */# : root用户是 */# ,普通用户是$ ,执行关机需要root用户
shutdown -h now */# 立刻关机,其中 now 相当于时间为 0 的状态
shutdown -h 20:25 */# 系统在今天的 20:25 分会关机,若在 21:25 才下达,则隔天才关机
shutdown -h +10 */# 系统再过十分钟后自动关机
shutdown -r now */# 系统立刻重新启动
shutdown -r +30 ‘The system will reboot‘ */# 再过三十分钟系统会重新启动,并显示后面的讯息给所有在线的使用者
shutdown -k now ‘This system will reboot‘ */# 仅发出警告信件的参数!系统并不会关机
Linux 文件系统的运作
由于磁盘写入的速度要比内存慢得多,所以大档案常常耗时在等待磁盘写入上
异步处理功能:
系统加载文件到内存,系统将档案数据放置到主存储器高速缓冲区,
如果没有被处理过,则为干净的(clean),如果被编辑过,内存中则为脏的(Dirty),此时动作还在内存执行,
系统会不定时回写脏数据到硬盘。保持一致性。手动或正常关机都会呼叫sync指令回写入硬盘,不正常关机后启动时会检查很久甚至造成文件损坏。
sync; sync; sync; reboot */#将数据同步写入硬盘中: sync(内存中尚未被更新的数据,就会被写入硬盘中,一般用户更新自己的数据 root更新整个系统中数据)
shutdown -h now */#惯用的关机: shutdown(透过 pietty 使用 ssh 从其他计算机登入主机,关机就只有 root 有权力)
poweroff -f
*/#Linux 提供 tty1~tty6 的文字接口登入以及 tty7 的图形接口登入环境 ,切换的方式为 Crtl + Alt + [F1]~[F6],[F7] 为图形接口,
重启 X 的组合键为:『[alt]+[ctrl]+[backspace]』
run level 0: */#关机
run level 3: */#纯文本模式 */#亦可使用 startx 进入图形环境
run level 5: */#含有图形接口模式
run level 6: */#重新启动
终端机的环境设定: stty, set
stty -a 列出所有的按键和按键的内容
stty erase ^h 删除是erase 设定ctrl+h为删除
echo $- 显示目前所有的 set 设定值
himBH bash 预设是 himBH,$- 变量内容就是 set 的所有设定
set -u
echo $vbirding 加了-u则未定义的变量不是为空而是报错,取消set+u
set -x 执行前显示指令
echo $HOME
*/------环境变量,PATH, env, set, export, echo, locale、read, declare, array, locale语言环境LANG和核心版本issue,历史记录history,别名alias, unalias-------
cat -n /etc/issue */# 查看系统版本 ,bash的进站与欢迎讯息: /etc/issue, /etc/motd,在/etc/issue里面更改开机信息,/etc/motd更改信息让大家都知道登录信息
*/# 除了 /etc/issue外还有个 /etc/issue.net ,是提供给 telnet 进程登录程序用的。
*/# 当我们使用 telnet 连接接主机时,主机的登入画面就会显示 /etc/issue.net 而不是etc/issue
nano /etc/issue */# 欢迎画面是在/etc/issue 档案中
CentOS release 5.3 (Final)
Kernel \r on an \m */# 核心版本是 \r ,硬件等级则是 \m
*/# 环境变量的功能:
env */# 列出目前shell 环境下的所有环境变量与其内容。
HOSTNAME=www.vbird.tsai */# 这部主机的主机名
TERM=xterm */# 这个终端机使用的环境是什么类型
SHELL=/bin/bash */# 目前这个环境下,使用的 Shell 是哪一个程序?
HISTSIZE=1000 */# 『记录指令的笔数』在 CentOS 默认可记录 1000 笔
USER=root */# 使用者的名称啊!
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:
set */# 观察所有环境变量与自定义变量
BASH=/bin/bash */# bash 的主程序放置路径
BASH_VERSINFO=([0]="3" [1]="2" [2]="25" [3]="1" [4]="release"
[5]="i686-redhat-linux-gnu") */# bash 的版本啊!
BASH_VERSION=‘3.2.25(1)-release‘ */# 也是 bash 的版本啊!
COLORS=/etc/DIR_COLORS.xterm */# 使用的颜色记录档案
COLUMNS=115 */# 在目前的终端机环境下,使用的字段有几个字符长度
HISTFILE=/root/.bash_history */# 历史命令记录的放置档案,隐藏档
HISTFILESIZE=1000 */# 存起来(与上个变量有关)的档案间指令的最大记录笔数。
HISTSIZE=1000 */# 目前环境下,可记录的历史命令最大笔数。
HOSTTYPE=i686 */# 主机安装的软件主要类型。我们用的是 i686 兼容机器软件
IFS=$‘ \t\n‘ */# 预设的分割符
LINES=35 */# 目前的终端机下的最大行数
MACHTYPE=i686-redhat-linux-gnu */# 安装的机器类型
MAILCHECK=60 */# 与邮件有关。每 60 秒去扫瞄一次信箱有无新信!
OLDPWD=/home */# 上个工作目录。
OSTYPE=linux-gnu */# 操作系统的类型!
PPID=20025 */# 父程序的PID (会在后续章节才介绍)
PS1=‘[\u@\h \W]\$ ‘ */# PS1 就厉害了。这个是命令提示字符,也就是我们常见的[root@www ~] */#或[dmtsai ~]$的设定值啦!
PS2=‘> ‘ */# 如果你使用跳脱符号 (\) 第二行以后的提示字符也
name=VBird */# 刚刚设定的自定义变量也可以被列出喔!
$ */# 目前这个 shell 所使用的PID
? */# 刚刚执行完指令的回传值
$:目前这个 Shell 的线程代号
『 echo $$ 』(本 shell的 PID)
?:(关于上个执行指令的回传值)
*/# 环境变量的取用与设定:echo,
echo $HOME-- echo ${HOME}
echo $MAIL-- echo ${MAIL}
echo $PATH-- echo ${PATH} */# 查看环境变量,使指令都能直接使用,一般用户与root用户变量不同,不包含sbin,但可以用绝对路径执行/sbin/ifconfig eho0
PATH 里面/usr/local/bin/ls和/bin/ls,哪个目录先被查到,哪个目录就会先执行。
mv /bin/ls /root */# 将指令移动后,即使在root下也不能执行ls,因为环境变量里没有设置。
./ls */# 执行
PATH="$PATH":/root */# 设置环境变量,处于安全考虑,不建议将『.』加入 PATH
*/# 中文编码有 big5与utf8 两种, Linux 系统默认支持的语系数据:和/etc/sysconfig/i18n 有关
echo $LANG */# 语言环境 或『locale』(影响显示结果的语系变量locale)
locale -a 目前linux支持多少种语言
locale 后面不加任何选项与参数即可,这些语言由哪些参数决定
ls -l `locate crontab` locate指令可列出所有的相关档案档名,列出crontab相关档名
cat /etc/sysconfig/i18n 整体系统默认的语系定义
/etc/sysconfig/i18n */# 系统配置文件也是修改系统默认语系
LANG=zh_TW.big5 */# 文件档案内编码为 big5 时,环境是Linux的GNOME
纯文本档案Windows下建立的格式为big5,上传到linux上需要在i18n上将软件编码由 utf8 改成 big5
*/# 语系编码转换: iconv
iconv -f big5 -t utf8 vi.big5 -o vi.utf8 /tmp/vitest/vi.big5 /tmp/vitest/vi.big5 转成 utf8 编码
file vi* 在用file看下类型
iconv -f utf8 -t big5 vi.utf8 | \ 那个 vi.utf8 转成简体的utf8
『var="lang is $LANG"』则『echo $var』可得『lang is en_US』 双引号
『var=‘lang is $LANG‘』则『echo $var』可得『lang is $LANG』 单引号
『version=$(uname -r)』再『echo $version』可得『2.6.18-128.el5 反单引号『`指令`』或 『$(指令)』
lsb_release -a
LSB Version: :core-3.1-amd64:core-3.1-ia32:core-3.1-noarch:graphics-3.1-amd64:
graphics-3.1-ia32:graphics-3.1-noarch */# LSB 的版本
Distributor ID: CentOS
Description: CentOS release 5.3 (Final) */# distribution 的版本
Release: 5.3
Codename: Final
uname -r
2.6.18-128.el5 */# 可以察看实际的核心版本
cd /lib/modules/$(uname -r)/kernel */# 目前核心模块目录
dmesg | grep ‘eth‘ */# dmesg 列出核心产生讯息!透过 grep 得网络卡相关信息 (eth)
PATH=$PATH:/home/dmtsai/bin
PATH="$PATH":/home/dmtsai/bin
PATH=${PATH}:/home/dmtsai/bin 扩增变量,都是对的
path=${PATH} 将变量path赋值
echo ${path */#/*kerberos/bin:} 从左到右删掉最短的目录
echo ${path */#/*:} 删除最短的目录有:的目录
echo ${path */# */#/*:} 删除掉最长的那个数据,直到:为止
*/# :符合取代文字的『最短的』那一个;
*/# */#:符合取代文字的『最长的』那一个
echo ${path%:*bin} % 符号代表由最后面开始向前删除第一个
echo ${path%%:*bin} %% 代表的则是由最后面开始向前最长的符合字符串
echo ${path/sbin/SBIN} */# 替换从左到右第一个
/usr/kerberos/SBIN:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:
/usr/sbin:/usr/bin:/root/bin
echo ${path//sbin/SBIN} */# 所有都替换
/usr/kerberos/SBIN:/usr/kerberos/bin:/usr/local/SBIN:/usr/local/bin:/SBIN:/bin:
/usr/SBIN:/usr/bin:/root/bin
echo ${MAIL */# */#/*/} */# 删除前面直到root『/var/spool/mail/root』
echo ${MAIL%/*} */# 删掉root『/var/spool/mail/root』
echo $myname
myname=VBird
echo $myname */# 给变量赋值
work="/cluster/server/work/taiwan_2005/003/" */# 用变量设置自己的工作目录
cd $work
unset myname */# 取消变量
name=VBird\‘s\ name */# 这种定义
name="VBird‘s name" */# 和这种定义都是对的
echo $username
username=${username-root}
echo $username
root */# 所以主动给予名为 root 的内容
username="vbird tsai" */# 设定username 的内容
username=${username-root}
echo $username
vbird tsai */# 因为 username 已经设定了,所以使用旧有的设定而不以 root取代
username=""
username=${username-root}
echo $username */# 设定为空的时候
username=${username:-root} */# 加上『 : 』后若变量内容为空或者是未设定,都能够以后面的内容替换!
变量设定方式 str 没有设定 str 为空字符串 str 已设定非为空字符串
var=${str-expr} var=expr var= var=$str
var=${str:-expr} var=expr var=expr var=$str
var=${str+expr} var= var=expr var=expr
var=${str:+expr} var= var= var=expr
var=${str=expr} str=expr str 不变 str 不变
var=expr var= var=$str
var=${str:=expr} str=expr str=expr str 不变
var=expr var=expr var=$str
var=${str?expr} expr 输出至 stderr var= var=$str
var=${str:?expr} expr 输出至 stderr expr 输出至 stderr var=$str
unset str; var=${str-newvar}
echo var="$var", str="$str"
var=newvar, str= */# 因为 str 不存在,所以 var 为 newvar
str="oldvar"; var=${str-newvar}
echo var="$var", str="$str"
unset str; var=${str=newvar}
echo var="$var", str="$str"
var=newvar, str=newvar */# 因为 str 不存在,所以 var/str 均为 newvar
str="oldvar"; var=${str=newvar}
echo var="$var", str="$str"
var=oldvar, str=oldvar */# 因为 str 存在,所以 var 等于 str 的内容
unset str; var=${str?无此变数}
-bash: str: 无此变量 */# 因为 str 不存在,所以输出错误讯息
str="oldvar"; var=${str?novar}
echo var="$var", str="$str"
var=oldvar, str=oldvar */# 因为 str 存在,所以 var 等于str 的内容
*/# export
Linux取得一个 bash后,bash 就是一个独立程序,被称为 PID,操作环境跑到第二个bash下原本的就休眠
子程序仅会继承父程序的环境变量, 子程序不会继承父程序的自定义变量,export可以让自定义变量变成环境变量
export PATH */# 使变量成为环境变量,在其他子程序执行
name=VBird
bash */# 进入子程序
echo $name */# 子程序:再次echo 一下;
*/# 嘿嘿!没有内容喔!
exit */# 子程序:离开这个子程序
export name
bash */# 进入子程序
echo $name */# 子程序:在此执行!
VBird */# 看吧!出值了!
exit */# 子程序:离开这个子程序
export
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="www.vbird.tsai"
declare -x INPUTRC="/etc/inputrc"
declare -x LANG="en_US"
declare -x LOGNAME="root" 将会把所有『环境变量』秀出, 将环境变量转成自定义变量 用declare
*/# 变量键盘读取、数组与宣告: read, declare, array
read
read atest
echo $atest */# 由键盘输入一内容,内容变成名为 atest的变量
read -p "Please keyin your name: " -t 30 named */# 30 秒内输入作为名为 named 变量内容
*/# read『 $变量 』有两种直接下达(通过script.sh 参数变量)和交互式(通过read读入键盘输入)
declare
declare -i sum=100+300+50
echo $sum
declare -i number=$RANDOM*10/32768 ; echo $number
8 */# 此时会随机取出0-9之间的数值(RANDOM 变量的内容,介于 0~32767 )
declare -x sum */# 将 sum 变成环境变量
export | grep sum
declare -ix sum="450" */# 果然出现了!包括有 i 与 x 的宣告!
declare -r sum
sum=tesgting
-bash: sum: readonly variable */# 让sum变成只读属性!
*/# 让 sum 变成非环境变量的自定义变量
declare +x sum */# 将 - 变成 + 可以进行『取消』动作
declare -p sum */# -p 可以单独列出变量的类型
declare -ir sum="450" */# 看吧!只剩下 i, r 的类型,不具有 x 啰!
数组
var[1]="small min"
var[2]="big min"
var[3]="nice min"
echo "${var[1]}, ${var[2]}, ${var[3]}"
small min, big min, nice min
*/# 环境配置文件: login, non-login shell, /etc/profile, ~/.bash_profile, source, ~/.bashrc
系统的合法 shell , /etc/shells 功能
*/# login shell与non-login shell
bash 配置文件的读入方式 ,透过一个指令『 source 』
1.login shell会读取的整体环境配置文件/etc/profile:
2. 读完了整体会读个人的文件:~/.bash_profile 或~/.bash_login 或 ~/.profile
不需要注销,将家目录的 ~/.bashrc 的设定读入目前的 bash 环境中
source ~/.bashrc */#底下这两个指令是一样的!
. ~/.bashrc
~/.bash_logout进行 history的记录,并加上 date 增加时间参数
习惯单一 bash 登入,再用工作控制 (job control, 第四篇会介绍) 切换不同工作
*/# 历史命令:
history */# 列出目前内存内的所有 history 记忆
history 3 */# 列出最近三笔
history -w */# 将目前资料写入histfile中, 默认记录写入~/.bash_history中
echo $HISTSIZE */# ~/.bash_history 记录的是前一次登入以前所执行过的指令
!66 */# 执行第 66 笔指令
!! */# 执行上一个指令,本例中亦即 !66
!al */# 执行最近以 al 为开头的指令(上头列出的第 67 个)
!vi 』 */# 执行最近指令开头是 vi 的指令列
*/# 命令名设定与删除: alias, unalias
alias lm=‘ls -al‘ */# 别名功能
执行顺序
1. 以相对/绝对路径执行指令,例如『 /bin/ls 』或『 ./ls 』;
2. 由 alias 找该指令执行;
3. 由 bash 内建的 (builtin) 指令执行;
4. 透过 $PATH 这个变量的顺序搜寻的第一个指令执行
type ls */# 找执行档,看是否为bash内建的
观察执行顺序
alias echo=‘echo -n‘
type -a echo
echo is aliased to `echo -n‘
echo is a shell builtin
echo is /bin/echo
*/-----文本编辑器有:emacs, pico,nano, joe, 与vim 等等 crontab, visudo, edquota等指令------------------
*/# vi的暂存档
编辑 /tmp/vitest/man.config 这个档案时, vim 会主动的建立/tmp/vitest/.man.config.swp的暂存档,
你对 man.config 做的动作就会被记录到这个 .man.config.swp 当中喔
vim 的一般模式下按下 [ctrl]-z 的组合按键时,你的 vim 会被丢到背景去执行
kill -9 %1 仿真断线停止 vim 工作
ls -al .man.config.swp 此时暂存档还存在,因为是不正常的停止vim,此时要自行删掉,按D删 按R载入。
*/# vim 环境设定与记录:
~/.viminfo */# 将用户经做过的行为登录下来
/etc/vimrc */# 整体 vim 的设定值一般是放置在这个档案
修改 ~/.vimrc 这个档案(自行手动建立!)
nano text.txt */# 存在就开启旧档,不存在就开启新档,类似vi
---------数据流,cat find, 截取cut, grep,sed ,egrep 排序sort, 去重uniq, 统计wc, 双导向tee, 字符转化tr,col,expand,
合成join,paste, 分割档案split,参数代换xargs,说明finger --------
标准输入 (stdin) :代码为 0 ,使用 < 或 << ;
2. 标准输出 (stdout):代码为 1 ,使用 > 或 >> ;
3. 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>>
cat > catfile */# 建立一个档案的简单流程,在键盘里输入后,ctrl+d结束后,cat catfile这个文件,此时可以看到输入记录已经存储到文件中了
cat > catfile < ~/.bashrc */# 复制功能,将原本需要由键盘输入的数据,改由档案内容取代
cat > catfile << "eof" */# 由键盘输入 eof 时,该次输入就结束
find /home -name .bashrc */# 身份是 dmtsai 喔!/home 底下还有其他账号存在,那些账号的家目录不能进入所以报错
find /home -name .bashrc > list_right 2> list_error */# 将报错的信息分别导向到不同的文档中
find /home -name .bashrc 2> /dev/null */# 将错误的数据丢弃,屏幕上显示正确的数据
find /home -name .bashrc > list 2> list */# 错误 两数据交叉写入该档案次序错乱
find /home -name .bashrc > list 2>&1 */# 正确
find /home -name .bashrc &> list */# 正确
ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe */# 不清楚 /tmp/abc 是否存在,但就是要建立 /tmp/abc/hehe 档案
ls /tmp/vbirding && echo "exist" || echo "not exist"
date >> ~/.myhistory
history 50 > > ~/.myhistory */# 备份指令记录 加入时间
『A=B』且『B=C』,下达『unset $A』, unset $A 相当于 unset B 所以取消的是 B ,A 会继续存在
foo1 && foo2 | foo3 > foo4 */# foo1, foo2 与foo3 都是指令, foo4 是装置或档案。整串指令意义为:
(1)当 foo1 执行结果有错误时,则该指令串结束;
(2)若 foo1 执行结果没有错误时,则执行 foo2 | foo3 > foo4 ;其中:
(2-1)foo2 将 stdout 输出的结果传给 foo3 处理;
(2-2)foo3 将来自 foo2 的 stdout 当成 stdin ,处理完后将数据流重新导向 foo4 这个装置/档案
排序命令: sort, 依据不同数据形态来排序,最好统一语系:LANG=C
cat /etc/passwd | sort 将帐号进行排序
cat /etc/passwd | sort -t ‘:‘ -k 3 */# 以第三栏的文本方式排序
cat /etc/passwd | sort -t ‘:‘ -k 3 -n */# 以第三栏的数字方式排序
last | cut -d ‘ ‘ -f1 | sort */# 仅取出帐号
去重命令:uniq,
last | cut -d ‘ ‘ -f1 | sort | uniq */# 排序后去重复
last | cut -d ‘ ‘ -f1 | sort | uniq -c */# 将重复次数显示,即登录次数
统计命令:wc
cat /etc/man.config | wc */# /etc/man.config 里面有多少『行、字数、字符数』
last | grep [a-zA-Z] | grep -v ‘wtmp‘ | wc -l */# 去除空白行和wtmp那行,进行登录总人数查询
双向重导向: tee :会同时将数据流分送到档案去与屏幕
> 会将数据流整个传送给档案或装置,除非去读取该档案或装置, 否则就无法继续用利用这个数据流
last | tee last.list | cut -d " " -f1 */# 在屏幕输出前,先存一份到档案中
ls -l /home | tee ~/homefile | more */# more 按页显示
ls -l / | tee -a ~/homefile | more */# -a不会将信息覆盖
字符转换命令: tr,
last | tr ‘[a-z]‘ ‘[A-Z]‘ */# 大写变小写,也可『 last | tr [a-z] [A-Z] 』
cat /etc/passwd | tr -d ‘:‘ */# 将冒号 (:) 删除
*/# DOS与Linux的断行字符
cat -A */# 来观察DOS (Windows 系统) 建立的档案的特殊格式为^M$,linux不一样是 ^M
unix2dos -k man.config */# 断行转为dos
dos2unix -k -n man.config man.config.linux */# 断行转成linux
cp /etc/passwd /root/passwd && unix2dos /root/passwd */# 将 /etc/passwd 转存成 dos 断行到 /root/passwd 中,再将 ^M 符号删除
file /etc/passwd /root/passwd
/etc/passwd: ASCII text
/root/passwd: ASCII text, with CRLF line terminators */# 就是 DOS 断行,此时有多的就是断行
cat /root/passwd | tr -d ‘\r‘ > /root/passwd.linux */# ^M 可以使用 \r ,去除 DOS 档案留下的 ^M断行,与原本的 /etc/passwd 就一致了!
字符转化命令:col,
cat -A /etc/man.config */# 很多 ^I就是 tab
cat /etc/man.config | col -x | cat -A | more */# [tab] 按键会被取代成为空格键
man col > /root/col.man */# 将 man page 转存为纯文本文件,带特殊字符
man col | col -b > /root/col.man */# 不带特殊字符
合成查询命令:join,
head -n 3 /etc/passwd /etc/shadow */# 将 /etc/passwd与 /etc/shadow 取3行
join -t ‘:‘ /etc/passwd /etc/shadow */# 两个档案第一字段相同者整合成一行
join -t ‘:‘ -1 4 /etc/passwd -2 3 /etc/group */# /etc/passwd 第四个字段是 GID ,那个 GID 记录在/etc/group 当中的第三个字段
所谓的 GID (账号的数字定义)/etc/passwd, /etc/shadow */# 以账号为相关性,/etc/passwd, /etc/group 则以 GID为相关性
合成查询命令:paste,
paste /etc/passwd /etc/shadow */# 将 /etc/passwd 与/etc/shadow 同一行贴在一起
cat /etc/group|paste /etc/passwd /etc/shadow -|head -n 3
*/# 先将 /etc/group 读出(用 cat),然后贴上前一个!取出前三行(那个 - 常常代表 stdin)
字符转换命令:expand */# 自动将 [tab] 转成空格键 ,unexpand 将空白转成 [tab]
grep ‘^MANPATH‘ /etc/man.config | head -n 3 */# 行首代表标志为 ^ 将 /etc/man.config 内行首为 MANPATH字样就取出
grep ‘^MANPATH‘ /etc/man.config | head -n 3 |cat -A */# 列出所有符号
grep ‘^MANPATH‘ /etc/man.config | head -n 3 | \ */# 将 [tab] 设成 6 个字符
> expand -t 6 - | cat -A
分割命令: split
cd /tmp; split -b 300k /etc/termcap termcap */# -b size 将一个分割档案限制其大小
ll -k termcap*
-rw-r--r-- 1 root root 300 Feb 7 16:39 termcapaa
-rw-r--r-- 1 root root 300 Feb 7 16:39 termcapab
-rw-r--r-- 1 root root 189 Feb 7 16:39 termcapac */# 大档案分割成为小档案
cat termcap* >> termcapback */# 数据流重导向小档案合成大档案
ls -al / | split -l 10 - lsroot */# 每十行记录成一个档案
wc -l lsroot*
参数代换: xargs */# 很多指令其实并不支持管线命令,可透过 xargs 来提供该指令引用 standard input之用
,inger account 可以取得该账号的相关说明内容
cut -d‘:‘ -f1 /etc/passwd |head -n 3| xargs finger */# xargs 将三个账号名称变成 finger 后面需要的参数
cut -d‘:‘ -f1 /etc/passwd |head -n 3| xargs -p finger */# 加询问-p
cut -d‘:‘ -f1 /etc/passwd | xargs -p -n 5 finger */# finger查阅帐号参数,但一次仅查阅五个
cut -d‘:‘ -f1 /etc/passwd | xargs -p -e‘lp‘ finger */# lp用来结束
find /sbin -perm +7000 | ls -l */# 不好使,列有root所在目录下的档案,因为ll (ls)并不是管线命令
find /sbin -perm +7000 | xargs ls -l */# 透过 xargs 提供ls以引用 standard input之用
类似管线命令:tar
tar -cvf - /home | tar -xvf - */# 一边压缩一边解压
管线命令,例如 less, more, head, tail 在|后的指令
ls -al /etc | less
echo $PATH | cut -d ‘:‘ -f 5 */# 将环境变量中第五个去除,分割符为:
echo $PATH | cut -d ‘:‘ -f 3,5 */# 取出3-5之间
export | cut -c 12- */# 取得第 12 字符以后的所有字符串,-c 可以处理比较具有格式的数据, cut -c 12-20区间
last | cut -d ‘ ‘ -f 1 */# 找出空格符第一个
grep
last | grep ‘root‘ */# 将出现了root的那一行取出。
last | grep -v ‘root‘ */# 没有root就取出
last | grep ‘root‘ |cut -d ‘ ‘ -f1 */# 取出root后的第一栏
grep --color=auto ‘MANPATH‘ /etc/man.config */# 取出 /etc/man.config 内含 MANPATH 的那几行
*/# grep的一些进阶选项
[:alnum:] 代表英文大小写字符及数字, 0-9, A-Z, a-z */# 正规表示法则是一种字符串处理的表示方式,不支持正规表示法的指令用通配符,
通配符 (wildcard) 代表的是 bash 操作接口的一个功能
[:alpha:] 代表任何英文大小写字符, A-Z, a-z
[:blank:] 代表空格键、 [Tab] 按键两者
[:cntrl:] 代表键盘上面控制按键,包括 CR, LF, Tab, Del.. 等等
[:digit:] 代表数字而已,0-9
[:graph:] 除了空格符 (空格键、 [Tab] 按键) 外的其他所有按键
[:lower:] 代表小写字符 a-z
[:print:] 代表任何可以被打印出的字符
[:punct:] 代表标点符号 (punctuation symbol):" ‘ ? ! ; : */# $...
[:upper:] 代表大写字符,A-Z
[:space:] 任何会产生空白的字符,包括空格键, [Tab], CR 等等
[:xdigit:] 代表 16 进位的数字类型,因此包括: 0-9, A-F, a-f的数字与字符
dmesg | grep ‘eth‘ */# dmesg 列出核心产生讯息!透过 grep 得网络卡相关信息 (eth)
dmesg | grep -n --color=auto ‘eth‘ */# 显色
dmesg | grep -n -A3 -B2 --color=auto ‘eth‘ */# 行号 前两行与后三行
alias grep=‘grep --color=auto‘
source ~/.bashrc */# 添加grep显示颜色的别名
grep -n ‘the‘ regular_express.txt */# 搜寻特定字符串
grep -vn ‘the‘ regular_express.txt */# 反向选择
grep -in ‘the‘ regular_express.txt */# 不论大小写
grep -n ‘t[ae]st‘ regular_express.txt */# 共通的 ‘t?st‘ 存在
grep -n ‘[^g]oo‘ regular_express.txt */# 不想要 oo 前面有 g
grep -n ‘[^a-z]oo‘ regular_express.txt */# 不想要有小写字符,小写字符的 ASCII 上编码的顺序是连续的
grep -n ‘[0-9]‘ regular_express.txt */# [a-z],[A-Z],[0-9]英文/小写英文/数字
grep -n ‘[^[:lower:]]oo‘ regular_express.txt */# [:lower:] 代表的就是 a-z
grep -n ‘[[:digit:]]‘ regular_express.txt
行首与行尾字符 ^ $
grep -n ‘^the‘ regular_express.txt */# the 只在行首列出
grep -n ‘^[a-z]‘ regular_express.txt */# 开头是小写字符的那一行就列出
grep -n ‘^[[:lower:]]‘ regular_express.txt */# 同上
grep -n ‘^[^a-zA-Z]‘ regular_express.txt */# 不想要开头是英文字母
grep -n ‘\.$‘ regular_express.txt */# 找小数点,使用跳脱字符(\)来加以解除小数点的特殊意义
cat -An regular_express.txt | head -n 10 | tail -n 6 */# 使用 cat -A 将第五行查出
5 However, this dress is about $ 3183 dollars.^M$ */# Windows 的断行字符 (^M$)
grep -n ‘^$‘ regular_express.txt */# 只有行首跟行尾 (^$),找出空白行
grep -v ‘^$‘ /etc/syslog.conf | grep -v ‘^ */#‘ */# 去除行首行尾是空白的以及用 */#开头的那些行。
正规表示法中
. (小数点):代表『一定有一个任意字符』的意思;
* (星星号):代表『重复前一个 0 到无穷多次』的意思,为组合形态
grep -n ‘g..d‘ regular_express.txt */# 重复 0 个或多个前面的 RE 字符
grep -n ‘g.*g‘ regular_express.txt */# 代表 g 开头与 g 结尾
grep -n ‘[0-9][0-9]*‘ regular_express.txt */# 仅有数字
grep -n ‘o*‘ regular_express.txt */# o*代表是:『没有字符或一个 o 以上的字符』会把所有的数据都打印出
grep -n ‘ooo*‘ regular_express.txt */# 至少两个 o 以上的字符串
grep -n ‘goo*g‘ regular_express.txt */# 两个 g 仅能存在至少一个 o
grep -n ‘g*g‘ regular_express.txt */# g*g 里面的 g* 代表『空字符或一个以上的g』
grep -n ‘o\{2\}‘ regular_express.txt */# 限定连续 RE 字符范围 ,两个 o 的字符
grep -n ‘go\{2,5\}g‘ regular_express.txt */# 2 到 5 个 o
grep -n ‘go\{2,\}g‘ regular_express.txt */# 2 个 o 以上
ls | grep -n ‘^a.*‘ */# 以 a 为开头的任何档名的档案
ls -l /etc | grep ‘^l‘ */# 文件类型为链接文件属性的文件名
grep ‘\*‘ /etc/* 在/etc下的带* 号的目录
grep ‘\*‘ $(find /etc -type f) 递归循环找etc下的目录中带*号的目录
grep ‘\*‘ $(find / -type f) 这样搜索/下的文件超过指令列的长度,透过管线命令以及 xargs
先用 find 去找出档案, 用 xargs 将这些档案每次丢 10 个给 grep 作为参数处理,grep 实际开始搜寻档案内容
find / -type f | xargs -n 10 grep ‘\*‘
取得IP
ifconfig eth0 | grep ‘inet addr‘ | sed ‘s/^.*inet addr://g‘| cut -d ‘ ‘ -f1
利用 alias 指定为 myip
alias myip="ifconfig eth0 | grep ‘inet addr‘ | sed ‘s/^.*inet addr://g‘| cut -d ‘ ‘ -f1 "
变量设定
MYIP=$( myip )
/etc 底下,只要含有 XYZ 三个字符的任何一个字符的那一行
grep [XYZ] /etc/*
/etc/termcap 内容去除开头为 */# 行 ,去除空白行 ,取出开头为英文字母行,最终统计总行数
grep -v ‘^ */#‘ /etc/ter
mcap | grep -v ‘^$‘ | grep ‘^[:alpha:]‘ | wc -l
sed 管线命令: */# 行的新增/删除, 行的取代/显示, 搜寻并取代, 直接改檔
nl /etc/passwd | sed ‘2,5d‘ */# 第 2~5 行删除的方式列出打印行号
nl /etc/passwd | sed ‘2d‘ */# 只要删除第 2 行
nl /etc/passwd | sed ‘3,$d‘ */# 删除第 3 到最后一行『 $ 』代表最后一行!
nl /etc/passwd | sed ‘2a drink tea‘ */# 加在第二行后即第三行 上『drink tea』字样
nl /etc/passwd | sed ‘2i drink tea‘ */# 加在第二行后即『 a 』变成『 i 』就可
nl /etc/passwd | sed ‘2,5c No 2-5 number‘ */# 2-5 行的内容取代成为『No 2-5 number』
nl /etc/passwd | sed -n ‘5,7p‘ */# head -n 7 | tail -n 5 被这种取代方式所,-n 代表不会重复输出是安静模式
/sbin/ifconfig eth0 | grep ‘inet addr‘ |sed ‘s/^.*addr://g‘ | sed ‘s/Bcast.*$//g‘ */# 查询 IP
inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
cat /etc/man.config | grep ‘MAN‘| sed ‘s/ */#.*$//g‘ | sed ‘/^$/d‘ */# 删掉批注和空白行
sed -i ‘s/\.$/\!/g‘ regular_express.txt 此命令会直接修改档案内容,将.变成!
sed -i ‘$a */# This is a test‘ regular_express.txt $ 代表的是最后一行,a 的动作是新增
延伸正规表示法 */# 『 | 』表示或 ,egrep、 grep -E 一样
grep -v ‘^$‘ regular_express.txt | grep -v ‘^ */#‘ 简化为 egrep -v ‘^$|^ */#‘ regular_express.txt
grep -n ‘[!>]‘ regular_express.txt 档案中含有 ! 不 >
--------格式化打印 printf ,awk打印数据------------------
printf: 格式化打印 ,不是管线命令
\a 警告声音输出
\b 退格键(backspace)
\f 清除屏幕 (form feed)
\n 输出新的一行
\r Enter 按键
\t 水平的 [tab] 按键
\v 垂直的[tab] 按键
\xNN NN 为两位数的数字,可以转换数字成为字符。
%ns 那个 n 是数字, s 代表 string ,亦即多少个字符;
%ni 那个 n 是数字, i 代表 integer ,亦即多少整数字数;
%N.nf 那个 n 与 N 都是数字, f 代表 floating (浮点),如果有小数字数,假设我共要十个位数,但小数点有两位,为 %10.2f 啰!
printf ‘%s\t %s\t %s\t %s\t %s\t \n‘ $(cat printf.txt)
printf ‘%10s %5i %5i %5i %8.2f \n‘ $(cat printf.txt | grep -v Name) */# 以字符串、整数、小数点来显示
printf ‘\x45\n‘ */# 16 进位数值 45 代表的字符
awk:好用的数据处理工具,处理每一行的字段内的数据
last -n 5 | awk ‘{print $1 "\t" $3}‘ 登录五行的数,打印第1栏和第3栏,以 [tab] 隔开
awk的处理流程是:
1. 读入第一行,并将第一行的资料填入 $0, $1, $2.... 等变数当中;
2. 依据 "条件类型" 的限制,判断是否需要进行后面的 "动作";
3. 做完所有的动作与条件类垄;
4. 若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。
NF 每一行 ($0) 拥有的字段总数
NR 目前 awk 所处理的是『第几行』数据
FS 目前的分隔字符,默认是空格键
非变量的文字部分都需要用双引号来定义
last -n 5| awk ‘{print $1 "\t lines: " NR "\t columes: " NF}‘
etc/passwd */# 冒号分割的数据第三栏即UID小于10以下的数据,打印第1栏和第3栏
cat /etc/passwd | awk ‘{FS=":"} $3 < 10 {print $1 "\t " $3}‘ */# 同上但命令仅从第二行开始生效,所以加入BEGIN 这个关键词
cat /etc/passwd | awk ‘BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}‘ */# 第一行不要进行加总,第二行以后就会有加总的情况出现
Name 1st 2nd 3th
VBird 23000 24000 25000
DMTsai 21000 20000 23000
Bird2 43000 42000 41000
第一种语法:
cat pay.txt | awk ‘NR==1{printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total" }
NR>=2{total = $2 + $3 + $4 printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}‘
Name 1st 2nd 3th Total
VBird 23000 24000 25000 72000.00
DMTsai 21000 20000 23000 64000.00
Bird2 43000 42000 41000 126000.00
第二种语法;
cat pay.txt | awk ‘{if(NR==1) printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"}
NR>=2{total = $2 + $3 + $4 printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}
pr 档案打印准备工具:
打印 /etc/man.config
pr /etc/man.config
*/--------执行 shell script,shell 身份, test, declare ----------------
*/# shell身份 (用whoami )所在的目录 (用 pwd )
*/#!/bin/bash
echo -e "Your name is ==> $(whoami)"
echo -e "The current directory is ==> $(pwd)"
透过 shell script启动一些服务 (services) 、 登录档分析管理啊、自动上传下载重要配置文件
*/# 执行shell的方式: shell.sh 只要有 r 的权限即可被执行, -n 及 -x 来检查、追踪 shell.sh
直接执行: shell.sh 或(需要设置PATH为~/bin/)
绝对路径+ shell.sh 或
相对路径+./shell.sh
bash执行: sh shell.sh, ./shell.sh ,bash shell.sh */# 不论是哪种script都会使用一个新的bash环境来执行脚本
*/# 当子程序完成后,在子程序内的各项变量或动作将会结束而不会传回传到父程序中
*/#/bin/sh 其实就是 /bin/bash (连结档) 即以 bash 的功能来执行 shell.sh
source shell.sh */# 但source就不一样
source ~/.bashrc */# 不注销系统而要让某些写入~/.bashrc 的设定生效时, 而不能使用 bash ~/.bashrc
vi sh01.sh
*/#!/bin/bash */# 宣告这个 script 使用的 shell 名称
*/# Program: */# 其他的 */# 都是『批注』用途
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "Hello World! \a \n" */# 主要程序部分
exit 0 */# 来让程序中断回传一个数值0给系统, echo $? 则可得到 0 的值
*/# exit n 自定错误讯息
chmod a+x sh01.sh; ./sh01.sh 来执行这个 script
vi sh02.sh
*/#!/bin/bash
read -p "Please input your first name: " firstname */# 提示使用者输入
read -p "Please input your last name: " lastname */# 提示使用者输入
echo -e "\nYour full name is: $firstname $lastname" */# 结果由屏幕输出
sh sh02.sh
echo $firstname $lastname
*/#两个变量并不存在喔!但是
source sh02.sh
echo $firstname $lastname
VBird Tsai */#嘿嘿!有数据产生喔!
*/# test 检测系统上面某些档案或者是相关的属性是否存在
test -e /dmtsai && echo "exist" || echo "Not exist"
1. 关于某个档名的『文件类型』判断,如 test -e filename 表示存在否
-e 该『档名』是否存在?(常用)
-f 该『档名』是否存在且为档案(file)?(常用)
-d 该『文件名』是否存在且为目录(directory)?(常用)
-b 该『档名』是否存在且为一个 block device 装置?
-c 该『档名』是否存在且为一个 character device 装置?
-S 该『档名』是否存在且为一个 Socket 档案?
-p 该『档名』是否存在且为一个 FIFO (pipe) 档案?
-L 该『档名』是否存在且为一个连结档?
2. 关于档案的权限侦测,如 test -r filename 表示可读否 (但 root 权限常有例外)
-r 侦测该档名是否存在且具有『可读』的权限?
-w 侦测该档名是否存在且具有『可写』的权限?
-x 侦测该档名是否存在且具有『可执行』的权限?
-u 侦测该文件名是否存在且具有『SUID』的属性?
-g 侦测该文件名是否存在且具有『SGID』的属性?
-k 侦测该文件名是否存在且具有『Sticky bit』的属性?
-s 侦测该档名是否存在且为『非空白档案』?
3. 两个档案之间的比较,如: test file1 -nt file2
-nt (newer than)判断 file1 是否比 file2 新
-ot (older than)判断 file1 是否比 file2 旧
-ef
判断 file1 与 file2 是否为同一档案,可用在判断 hard link 的判定上。 主要在判定,两个档案是否均指向同一个 inode 哩!
4. 关于两个整数之间的判定,例如 test n1 -eq n2
-eq 两数值相等 (equal)
-ne 两数值不等 (not equal)
-gt n1 大于 n2 (greater than)
-lt n1 小于 n2 (less than)
-ge n1 大于等于 n2 (greater than or equal)
-le n1 小于等于 n2 (less than or equal)
5. 判定字符串的数据
test -z string 判定字符串是否为 0 ?若 string 为空字符串,则为 true
test -n string 判定字符串是否非为 0 ?若 string 为空字符串,则为 false。注: -n 亦可省略
test str1 = str2 判定 str1 是否等于 str2 ,若相等,则回传 true
test str1 != str2 判定 str1 是否不等于 str2 ,若相等,则回传 false
6. 多重条件判定,例如: test -r filename -a -x filename
-a
(and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有r 与 x 权限时,才回传 true。
-o
(or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。
! 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true
vi sh05.sh
*/#!/bin/bash
echo -e "Please input a filename, I will check the filename‘s type and permission. \n\n"
read -p "Input a filename : " filename
test -z $filename && echo "You MUST input a filename." && exit 0 */# 判断是否有输入档案名字符串否则离开
test ! -e $filename && echo "The filename ‘$filename‘ DO NOT exist" && exit 0 */# 判断档案是否存在,不存在则显示讯息再离开
test -f $filename && filetype="regulare file" */# 判断文件类型与属性
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writable"
test -x $filename && perm="$perm executable"
echo "The filename: $filename is a $filetype" */# 开始输出信息
*/# declare 来定义变量为整数才能进行数值运算或采用『 $((计算式)) 』来进行数值运算
vi sh04.sh
*/#!/bin/bash
echo -e "You SHOULD input 2 numbers, I will cross them! \n"
read -p "first number: " firstnu
read -p "second number: " secnu
total=$(($firstnu*$secnu))
echo -e "\nThe result of $firstnu x $secnu is ==> $total"
*/--netstat, date,read, case in ..esac,,判断用中括号、 && 与 ||,read语法及参数设定,
while do done, until do done,for...do...done---------------
*/# 主机 IP 的侦测
netstat -a */# netstat 的指令可以查询到目前主机有开启的网络服务端口 (service ports) 看网络的联机状态
netstat -tuln */# 取得目前主机有启动的服务
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 :::22 :::* LISTEN
udp 0 0 0.0.0.0:111 0.0.0.0:*
udp 0 0 0.0.0.0:631 0.0.0.0:*
*/#封包格式 本地 IP:端口 远程 IP:端口 是否监听
*/# 本地 IP:端口(是本机所启动的网络服务)
*/# 127.0.0.1 则是仅针对本机开放,若是0.0.0.0 或 ::: 则代表对整个 Internet 开放 ,
*/# ip 说明该服务位于哪个接口上,port说明其特定的网络服务。
80: WWW
22: ssh
21: ftp
25: mail
111: RPC(进程过程调用)
631: CUPS(打印服务功能)
*/# 用netstat命令监测我的主机是否有开启这四个主要的网络服务端口
/sbin/ifconfig eth0 | grep ‘inet addr‘ |sed ‘s/^.*addr://g‘ | sed ‘s/Bcast.*$//g‘ */# 查询 IP
inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
*/# 用 ping 判断网络状态的指令, 来进行网络状态的实际侦测时,我想要侦测的网域是本机所在的192.168.1.1~192.168.1.100
vi sh17.sh
*/#!/bin/bash
network="192.168.1" */# 先定义一个网域的前面部分!
for sitenu in $(seq 1 100) */# seq 为 sequence(连续) 的缩写之意
do */# 底下的程序在取得 ping 的回传值是正确的还是失败的!
ping -c 1 -w 1 ${network}.${sitenu} &> /dev/null && result=0 || result=1
*/# 开始显示结果是正确的启动 (UP) 还是错误的没有连通 (DOWN)
if [ "$result" == 0 ]; then
echo "Server ${network}.${sitenu} is UP."
else
echo "Server ${network}.${sitenu} is DOWN."
fi
done
vi sh10.sh
*/#!/bin/bash
echo "Now, I will detect your Linux server‘s services!" 告知
echo -e "The www, ftp, ssh, and mail will be detect! \n" 测试也输出一些信息!
testing=$(netstat -tuln | grep ":80 ") */# 侦测看 port 80 在否?
if [ "$testing" != "" ]; then
echo "WWW is running in your system."
fi
testing=$(netstat -tuln | grep ":22 ") */# 侦测看 port 22 在否?
if [ "$testing" != "" ]; then
echo "SSH is running in your system."
fi
testing=$(netstat -tuln | grep ":21 ") */# 侦测看 port 21 在否?
if [ "$testing" != "" ]; then
echo "FTP is running in your system."
fi
testing=$(netstat -tuln | grep ":25 ") */# 侦测看 port 25 在否?
if [ "$testing" != "" ]; then
echo "Mail is running in your system."
fi
*/# date 以前天、昨天、今天的日期来建立档案
date */#当前系统时间
date +%Y/%m/%d */#年月日
date +%H:%M */#时间格式化
vi sh03.sh
*/#!/bin/bash
echo -e "I will use ‘touch‘ command to create 3 files." */# 纯粹显示信息
read -p "Please input your filename: " fileuser */# 提示使用者输入
filename=${fileuser:-"filename"} */# 开始判断有否配置文件名,判断是为了避免使用者随意按 Enter
date1=$(date --date=‘2 days ago‘ +%Y%m%d) */# 前两天的日期,开始利用 date 指令来获得所需要的档名
date2=$(date --date=‘1 days ago‘ +%Y%m%d) */# 前一天的日期
date3=$(date +%Y%m%d) */# 今天的日期
file1=${filename}${date1} */# 底下三行在配置文件名
file2=${filename}${date2}
file3=${filename}${date3}
touch "$file1" */# 底下三行在建立档案
touch "$file2"
touch "$file3"
*/# 你还有几天可以过生日
*/#!/bin/bash
read -p "Pleas input your birthday (MMDD, ex> 0709): " bir
now=`date +%m%d`
if [ "$bir" == "$now" ]; then
echo "Happy Birthday to you!!!"
elif [ "$bir" -gt "$now" ]; then
year=`date +%Y`
total_d=$(($((`date --date="$year$bir" +%s`-`date +%s`))/60/60/24))
echo "Your birthday will be $total_d later"
else
year=$((`date +%Y`+1))
total_d=$(($((`date --date="$year$bir" +%s`-`date +%s`))/60/60/24))
echo "Your birthday will be $total_d later"
fi
*/# 让用户输入他的退伍日期,帮他计算还有几天才退伍?
vi sh11.sh
*/#!/bin/bash
...
echo "This program will try to calculate :"
echo "How many days before your demobilization date..."
read -p "Please input your demobilization date (YYYYMMDD ex>20090401): " date2 */# 告知应该如何输入日期格式?
date_d=$(echo $date2 |grep ‘[0-9]\{8\}‘) */# 测输入的内容是否正确?看看是否有八个数字
if [ "$date_d" == "" ]; then
echo "You input the wrong date format...."
exit 1
fi 开始计算日期
declare -i date_dem=`date --date="$date2" +%s` */# 退伍日期秒数
declare -i date_now=`date +%s` */# 现在日期秒数
declare -i date_total_s=$(($date_dem-$date_now)) */# 剩余秒数统计
declare -i date_d=$(($date_total_s/60/60/24)) */# 转为日数 (24 小时*60 分*60 秒)
if [ "$date_total_s" -lt "0" ]; then */# 判断是否已退伍
echo "You had been demobilization before: " $((-1*$date_d)) "
ago"
else
declare -i date_h=$(($(($date_total_s-$date_d*60*60*24))/60/60))
echo "You will demobilize after $date_d days and $date_h hours."
fi
*/# 判断用中括号、 && 与 ||
[ -z "$HOME" ] ; echo $? */# 判断home这个目录是否为空,echo $? 则可得到 0 的值
[ "$HOME" == "$MAIL" ] */# 中括号方式要加空格分割,bash一个等号和两个等号是一样的,
此处为逻辑判断,相当于 test $HOME = $MAIL
vi sh06.sh
*/#!/bin/bash
read -p "Please input (Y/N): " yn
[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK, continue" && exit 0
[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh, interrupt!" && exit 0
echo "I don‘t know what your choice is" && exit 0
*/# read用法
vi sh12.sh
*/#!/bin/bash
echo "This program will print your selection !"
*/# read -p "Input your choice: " choice */# 暂时取消,可以替换!
*/# case $choice in */# 暂时取消,可以替换!
case $1 in */# 现在使用,可以用上面两行替换!
"one")
echo "Your choice is ONE"
;;
"two")
echo "Your choice is TWO"
;;
"three")
echo "Your choice is THREE"
;;
*)
echo "Usage $0 {one|two|three}"
;;
esac
*/# read 功能是由键盘输入一些判断式。指令后面接参数
read 功能是由键盘输入一些判断式。指令后携带参数的 script:
script 针对参数设定好了一些变量名称
/path/to/scriptname opt1 opt2 opt3 opt4
$0 $1 $2 $3 $4
脚本档名 $ */# :代表后接的参数『个数』,以上表为例这里显示为『 4 』;
$@ :代表『 "$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);
$* :代表『 "$1c$2c$3c$4" 』,其中 c 为分割字符,默认为空格键, 所以本例中代表『 "$1 $2 $3 $4" 』之意。
vi sh07.sh
*/#!/bin/bash
echo "The script name is ==> $0" */# 程序的文件名
echo "Total parameter number is ==> $ */#" */# 共有几个参数
[ "$ */#" -lt 2 ] && echo "The number of parameter is less than 2. Stop here." && exit 0
若参数的个数小于2则告知使用者参数数量太少
echo "Your whole parameter is ==> ‘$@‘" */# 全部的参数内容为何
echo "The 1st parameter ==> $1" */# 第一个参数为何
echo "The 2nd parameter ==> $2"
shift */# 进行第一次『一个变量的 shift 』
sh sh08.sh one two three four five six */# 这个shift添加到脚本中,执行时会进行参数偏移
Your whole parameter is ==> ‘one two three four five six‘
Total parameter number is ==> 5 */# 第一次偏移,第一个 one不见了
*/# read 后添加:
[ "$yn" == "Y" -o "$yn" == "y" ] */# 将多个条件写入一个中括号内的情况。
上式可替换为
[ "$yn" == "Y" ] || [ "$yn" == "y" ]
vi sh06-2.sh
*/#!/bin/bash
read -p "Please input (Y/N): " yn
if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
echo "OK, continue"
exit 0
fi
if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
echo "Oh, interrupt!"
exit 0
fi
echo "I don‘t know what your choice is" && exit 0
用if elif then else then fi代替 if,避免重复判断
read -p "Please input (Y/N): " yn
if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
echo "OK, continue"
elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
echo "Oh, interrupt!"
else
echo "I don‘t know what your choice is"
fi
*/#!/bin/bash
vi sh09.sh
if [ "$1" == "hello" ]; then
echo "Hello, how are you ?"
elif [ "$1" == "" ]; then
echo "You MUST input parameters, ex> {$0 someword}"
else
echo "The only parameter is ‘hello‘, ex> {$0 hello}"
fi
1. 判断 $1 是否为 hello,如果是的话,就显示 "Hello, how are you ?";
2. 如果没有加任何参数,就提示使用者必须要使用的参数下达法;
3. 而如果加入的参数不是 hello ,就提醒使用者仅能使用 hello 为参数。
*/# 做大小写转化:
vi sh12-2.sh
*/#!/bin/bash
function printit(){
echo -n "Your choice is " */# 加上 -n 可以不断行继续在同一行显示
}
echo "This program will print your selection!"
case $1 in
"one")
printit; echo $1 | tr ‘a-z‘ ‘A-Z‘ */# 将参数做大小写转换!
;;
"two")
printit; echo $1 | tr ‘a-z‘ ‘A-Z‘
;;
"three")
printit; echo $1 | tr ‘a-z‘ ‘A-Z‘
;;
*)
echo "Usage $0 {one|two|three}"
;;
esac
*/# case in ..esac语法 屏幕上就会出现『Usage sh09-2.sh {hello}』的字样
vi sh09-2.sh
*/#!/bin/bash
...
case $1 in
"hello")
echo "Hello, how are you ?"
;;
"")
echo "You MUST input parameters, ex> {$0 someword}"
;;
*) */# 其实就相当于通配符,0~无穷多个任意字符之意!
echo "Usage $0 {hello}"
;;
esac
*/# print()里的参数 $1依据的是传给方法的参数值
vi sh12-3.sh
*/#!/bin/bash
function printit(){
echo "Your choice is $1" */# 这个 $1 必须要参考底下指令的下达
}
echo "This program will print your selection !"
case $1 in
"one")
printit 1 */# 请注意, printit 指令后面还有接参数!
;;
"two")
printit 2
;;
"three")
printit 3
;;
*)
echo "Usage $0 {one|two|three}"
;;
esac
*/# while do done ,until do done
vi sh13.sh */# 循环 (loop) while do done 条件成立就循环, until do done (不定循环)条件不成立就循环直到条件成立
*/#!/bin/bash
while [ "$yn" != "yes" -a "$yn" != "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."
vi sh13-2.sh
*/#!/bin/bash
until [ "$yn" == "yes" -o "$yn" == "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."
vi sh14.sh
*/#!/bin/bash
s=0 */# 这是加总的数值变数
i=0 */# 这是累计的数值,亦即是 1, 2, 3....
while [ "$i" != "100" ]
do
i=$(($i+1)) */# 每次 i 都会增加 1
s=$(($s+$i)) */# 每次都会加总一次!
done
echo "The result of ‘1+2+3+...+100‘ is ==> $s"
*/# for...do...done (固定循环)已经知道要进行几次循环
vi sh15.sh
*/#!/bin/bash
for animal in dog cat elephant
do
echo "There are ${animal}s.... "
done
*/# 汲取账号信息
系统上面的各种账号都是写在 /etc/passwd 内的第一个字段,透过管线命令的 cut 捉出单纯的账号名称后,
使用循环处理,以 id 及 finger 分删检查使用者的标识符与特殊参数。
vi sh16.sh
*/#!/bin/bash
users=$(cut -d ‘:‘ -f1 /etc/passwd) */#汲取账号名称
for username in $users */#开始循环进行!
do
id $username
finger $username
done
*/# for循环
vi sh19.sh
*/#!/bin/bash
read -p "Please input a number, I will count for 1+2+...+your_input: " nu
s=0
for (( i=1; i<=$nu; i=i+1 ))
do
s=$(($s+$i))
done
echo "The result of ‘1+2+3+...+$nu‘ is ==> $s"
sh -n sh16.sh此方法判断一个脚本有无语法问题
sh -x sh15.sh此方法将脚本执行的过程全部列出 +后面的数据其实都是指令串
*/# 当输入数字等于循环的i时跳出否则计算1到输入的数字总和
*/#!/bin/bash
read -p "Please input an integer number: " number
i=0
s=0
while [ "$i" != "$number" ]
do
i=$(($i+1))
s=$(($s+$i))
done
echo "the result of ‘1+2+3+...$number‘ is ==> $s"
*/#!/bin/bash
if [ ! -e logical ]; then
touch logical
echo "Just make a file logical"
exit 1
elif [ -e logical ] && [ -f logical ]; then
rm logical
mkdir logical
echo "remove file ==> logical"
echo "and make directory logical"
exit 1
elif [ -e logical ] && [ -d logical ]; then
rm -rf logical
echo "remove directory ==> logical"
exit 1
else
echo "Does here have anything?"
fi
*/# 找出某目录内的文件名的权限
*/#!/bin/bash
read -p "Please input a directory: " dir */#先看看这个目录是否存在
if [ "$dir" == "" -o ! -d "$dir" ]; then
echo "The $dir is NOT exist in your system." exit 1
fi */#开始测试档案
filelist=$(ls $dir) */# 列出所有在该目录下的文件名
for filename in $filelist
do
perm=""
test -r "$dir/$filename" && perm="$perm readable"
test -w "$dir/$filename" && perm="$perm writable"
test -x "$dir/$filename" && perm="$perm executable"
echo "The file $dir/$filename‘s permission is $perm "
done
*/---------Linux 目录配置的依据--FHS---------------
FHS :用于规范每个特定的目录下应该要放置什么样的数据
可分享的(shareable) 可以分享给其他系统挂载使用的目录 不可分享的(unshareable)
不变的(static) 经常改变的数据 /usr (软件放置处) /etc (配置文件)
/opt (第三方协力软件) /boot (开机不核心档)
可变动的(variable) /var/mail (使用者邮件信箱) /var/run (程序相关)
/var/spool/news (新闻组) /var/lock (程序相关)
/(root, 根目录): 与开机系统有关,根目录(/)所在分割槽应该越小越好
/usr (unix software resource):与软件安装/执行有关,类似『C:\Windows\ + C:\Program files\』的综合体,distribution 发布者提供的软件
/var (variable): 与系统运作过程有关,常态怅变动的大容量档案,
如:快取(cache)、登录档(log file)以及某些软件运作
所产生的档案, 包括程序档案(lock file, run file),或者例如 MySQL 数据库的档案
MySQL 的数据库放置到/var/lib/mysql/而rpm 的数据库则放到/var/lib/rpm
/var/log:摆放系统注册表档案的地方
/var/log/messages, /var/log/wtmp(记录登入者的信息)
/var/run/服务启动后PID放在此目录下。
/var/spool/通常放置一些队列数据
工作排程数据(crontab),就会被放置到/var/spool/cron/
/bin 在单人维护模式下还能执行文件的指令,/usr/bin与/bin都是一般执行档。与/usr/bin/不同在于是否与开机有关
『./run.sh』执行本目录下, 名为 run.sh 的档案,bin, /usr/bin 目录下的指令可以直接执行。
/boot 开机配置文件,还会存在/boot/grub/,也是预设摆放核心 vmlinuz 的地方
/dev 设备装置
/etc 系统主要的配置文件,几乎系统的所有配置文件案均在此,尤其 passwd,shadow
/etc/inittab,
/etc/rc.d/rc.local 开机加载程序的项目 (就是在 /etc/rc.d/rc.local 里头的数据)
/etc/init.d */#/Linux 系统的所有服务(services) 预设启动的接口,所有档案都是 scripts , 开机加载程序的项目
(就是在 /etc/rc.d/rc.local 里头的数据)
/etc/init.d/iptables start */#防火墙连续规则 (iptables)
/etc/init.d/iptables stop */#启动或关闭 iptables 的话
file /etc/init.d/syslog */#使用 file 来查询后,系统告知这个档案是个 bash 的可执行 script 喔!
/etc/init.d/syslog: Bourne-Again shell script text executable
/etc/init.d/syslogd restart */#在脚本档名后+参数,重新启动系统注册表档,syslogd 档案就是 script,
这个脚本在启动一个名为 syslog 的常驻程序,
/etc/init.d/syslog */#会出现用法,帮助很多系统服务记载它们的登录文件。
用法:/etc/init.d/syslog {start|stop|status|restart|condrestart}
/etc/modprobe.conf,
/etc/xinetd.d/: super daemon 管理的各项服务的配置文件
/etc/X11/ 与 X Window 有关的各种配置文件
/etc/fstab, /etc/sysconfig/ 等等
/home 用户家目录
/lib 函式库 /lib/modules/放置核心相关的模块(驱动程序)
/media 可移除的装置都暂时挂载于此如/media/floppy, /media/cdrom
/mnt 同上
/opt 第三方协力软件放置的目录非原本的distribution 提供的,能安装到这里 。
/root 单人维护模式下且仅挂载根目录时,就拥有root家目录
该目录就能够拥有 root 的家目录,所以我们会希服 root 的家目录与根目录放置在同一个分割槽中。
/sbin 开机过程中所需,开机、修复、还原系统指令,/usr/sbin, /sbin:系统管理员常用指令集,
与/bin不同在于是系统管理员还是一般用户管用,
与/usr/sbin/不同在于是否开机
与/usr/local/sbin/不同在于是否本机自行安装的软件所产生的系统执行文件 (如fdisk,fsck,ifconfig, init, mkfs 等等)
/srv 『service』的缩写,网络服务启动后取用的。
/tmp 一般用户暂时放置档案定期的清理
/lost+found 文件系统发生错误,这个目录通常会在分割槽的最顶层存在
/pro 系统核心、行程信息
(/proc/cpuinfo, /proc/dma, /proc/interrupts,
/proc/ioports, /proc/net/*数据都是在内存当中)
/sys 跟/proc 类似的虚拟的文件系统
*/-----磁盘 df, du ,df ,dumpe2fs ,fdisk ,mkfs, fsck, mount, umount 与目录的容量-------
du:评估文件系统的磁盘使用量(帯用在推估目录所占容量) 以K计数,-m以MB计数
du -a */# 列出档案容量
du -sm /* */# 检查根目录下每个目录所占容量 利用通配符 * 来代表每个目录
du m /*
df:列出文件系统的整体磁盘使用量;
df
tmpfs 371332 0 371332 0% /dev/shm */#是与内存有关的挂载,利用内存虚拟出来的磁盘空间,开机就消失了,速度快
df -h
df -h /etc
df -aT */# 系统内的所有特殊文件格式及名称都列出来,如/proc 这个挂载点都是在内存当中不占硬盘
(/proc是Linux 系统所需要加载的系统数据)
df -ih */# 列出可用的 inode 剩余量与总容量
dumpe2fs /dev/sda1
dumpe2fs 1.39 (29-May-2006)
Filesystem volume name: /1 */#这个是文件系统的名称(Label)
Filesystem features: has_journal ext_attr resize_inode dir_index
filetype needs_recovery sparse_super large_file
Default mount options: user_xattr acl */#预设挂载的参数
Filesystem state: clean */#这个文件系统是没问题的(clean)
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 2560864 */#inode 的总数
Block count: 2560359 */#block 的总数
Free blocks: 1524760 */#还有多少个 block 可用
Free inodes: 2411225 */#还有多少个 inode 可用
First block: 0
Block size: 4096 */#每个 block 的大小啦!
Filesystem created: Fri Sep 5 01:49:20 2008
Last mount time: Mon Sep 22 12:09:30 2008
Last write time: Mon Sep 22 12:09:30 2008
Last checked: Fri Sep 5 01:49:20 2008
First inode: 11
Inode size: 128 */#每个 inode 的大小
Journal inode: 8 */#128MB 的容量在处理日志呢
Journal backup: inode blocks
Journal size: 128M
*/---------以下是superblocks
Group 0: (Blocks 0-32767) */#第一个 data group 内容, 包含 block 起始和结束
Primary superblock at 0, Group descriptors at 1-1 */#超级区块在 0 号block
Reserved GDT blocks at 2-626
Block bitmap at 627 (+627), Inode bitmap at 628 (+628)
Inode table at 629-1641 (+629) */#inode table 所在的 block
0 free blocks, 32405 free inodes, 2 directories */#所有 block 都用完了!
Free blocks:
Free inodes: 12-32416 */#剩余未使用的 inode 号码
Group 1: (Blocks 32768-65535)
磁盘分区: fdisk,列出系统内所有能搜到的装置,配合 df /用,fdisk只有 root才能执行
fdisk /dev/hdc */#不加上数字则下面会提示命令。
Command (m for help): m */# 输入 m 后,就会看到底下这些介绍
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition */#删除一个 partition
l list known partition types
m print this menu
n add a new partition */#新增一个 partition
o create a new empty DOS partition table
p print the partition table */#在屏幕上显示分割表
q quit without saving changes */#不储存离开 fdisk 程序
s create a new empty Sun disklabel
t change a partition‘s system id
u change display/entry units
v verify the partition table
w write table to disk and exit */#将刚刚的动作写入分割表
x extra functionality (experts only) partprobe
Command (m for help): p */# 这里可以输出目前整体磁盘的状态及磁盘分割表
也可以新增和删除分隔槽。,新增后写如分割表后核心无法捉到分割信息利用partprobe指令则不需要reboot
利用GNU的parted 进行分割行为:fdisk 没有办法处理大于 2TB 以上的磁盘分区槽,则用parted指令解决。
parted /dev/hdc print */#以 parted 列出目前本机的分割表资料,第六列如同 fdisk的System ID 。
parted /dev/hdc mkpart logical ext3 19.2GB 19.7GB */#建立一个约为 512MB 容量的逻辑分割槽,
dev/hdc7 在 19.2GB 位置结束从这开始分割
parted /dev/hdc rm 8 */#将8号磁盘分区删除
磁盘格式化: mkfs,
mkfs -t ext3 /dev/hdc6 系统会去呼叫 mkfs.ext3,将新分割出来的分区进行Ext3文件系统格式化。
mkfs -t vfat /dev/hdc6 格式化为wind可读的vfat
mke2fs后面参数加的多:mke2fs -j -L "vbird_logical" -b 2048 -i 8192 /dev/hdc6
磁盘检验: fsck,
fsck -C -f -t ext3 /dev/hdc6 系统会呼叫呼叫e2fsck软件,对装置检验,-f 强制检查系统出现极大问题,
root权限在单人模式下执行,否则不要执行,会对系统造成大伤害。
且被检查的硬盘需是卸载状态。检查后有问题则放入『lost+found』文件中。
*/#硬盘坏了,出错扇区所挂载的目录不同:
1.根目录『/』并没有损毁,发生错误的 partition 是在/dev/sda7 这一块
开机输入 root 密码,单人单机的维护工作,输入『 fsck /dev/sda7 』进行文件系统检查 clear [Y/N]? Y,reboot
2.根目录损毁了,将硬盘拔掉,接到另一台 Linux 系统,先用Live CD 光盘开机,不要挂载,以 root 的身份执行『 fsck /dev/sdb1 』 去修复原本的根目录
3.整个硬盘坏了,根据分区去抢救:
/
/boot
/usr
/home
/var
badblocks */#检查硬盘或软盘扇区是否有坏道。
磁盘挂载与卸除: mount, umount */# 目录的挂载可以用本地的文件系统,也可用网络的 Network File System (NFS) 服务器挂载某特定目录
*/# 挂载点的意义(mount point)
单一文件系统不应该被重复挂载在不同的挂载点(目录)中;
单一目录不应该重复挂载多个文件系统;
要作为挂载点的目录,理论上应该都是空目录才是。
*/# 系统挂载的一些限制:
根目录 / 是必项挂载的﹐而且一定要先于其它 mount point 被挂载进来。
其它 mount point 必项为已建立的目录﹐可任意指定﹐但一定要遵守必项的系统目录架构原则
所有 mount point 在同一时间内﹐只能挂载一次。
所有 partition 在同一时间内﹐只能挂载一次。
正在使用的文件系统不能挂载
如若进行卸除﹐您必项先将工作目录移到 mount point(及其子目录) 外。
*/# VFS 的功能来管理所有的filesystem,指定什么文件系统来读什么文件。
ls -l /lib/modules/$(uname -r)/kernel/fs linux查看支持的文件系统, Linux支持的文件系统驱动程序都写在这里
cat /proc/filesystems 目前加载到内存中支持的文件系统
/etc/filesystems: 系统指定的测试挂载文件系统类型;
mount -l 目前已经挂载的文件
*/# 哪5个目录不可与根目录分开?开机过程中仅有根目录会被挂载, 其他分割槽则是在开机完成后才会持续的挂载
/etc:配置文件
/bin:重要执行档
/dev:所需要的装置档案
/lib:执行档所需的函式库不核心所需的模块
/sbin:重要的系统执行文件,与/usr/sbin/不同的是:是否非系统正常使用的系统指令
*/# 挂载文件系统
mkdir /mnt/hdc6
mount /dev/hdc6 /mnt/hdc6
df
/dev/hdc6 1976312 42072 1833836 3% /mnt/hdc6 */# 挂载文件系统
mkdir /media/cdrom
mount -t iso9660 /dev/cdrom /media/cdrom
mount /dev/cdrom /media/cdrom */# 挂载光盘
mkfs -t vfat /dev/fd0 */# 挂载软盘先用mkfs格式化,
mkdir /media/floppy */# 我们格式化软盘成为 Windows/Linux 可共同使用的FAT 格式吧!
mount -t vfat /dev/fd0 /media/floppy
df
mkdir /mnt/home
mount --bind /home /mnt/home */# 将 /home 目录暂时挂载到 /mnt/home 底下
ls -lid /home/ /mnt/home */# mount --bind,两者连结到同一个 inode,类似连接档
2 drwxr-xr-x 6 root root 4096 Sep 29 02:21 /home/ */# 从此进入 /mnt/home 就是进入/home
2 drwxr-xr-x 6 root root 4096 Sep 29 02:21 /mnt/home
mount -l
/home on /mnt/home type none (rw,bind)
*/# 文件系统开机自动挂载 /etc/fstab 及 /etc/mtab,
*/# CentOS 的配置文件/etc/fstab 档案的设定都预设使用 Label name(分割槽别名方式挂载)
dumpe2fs -h /dev/hdc6 */# dumpe2fs查出使用文件系统的标头(label)名称
Filesystem volume name: vbird_logical
mount -L "vbird_logical" /mnt/hdc6 */# 使用 Label name 进行挂载
dumpe2fs -h /dev/hdc6 */# 若插了两个相同别名的硬盘,会不知道读哪个
e2label /dev/hdc6 "my_test" */# 改标题
dumpe2fs -h /dev/hdc6 */# 再查看看到标题变了
tune2fs -l /dev/hdc6 */# 列出 /dev/hdc6的superblock 内容
cat /etc/fstab */#用mount挂载后将参数写入/etc/fstab中,fstab中加入了 dump 这个备份
devpts /dev/pts devpts gid=5,mode=620 0 0
装置文件名或该Label 挂载点 文件系统参数 能否被 dump 备份(1每天备份) 是否以 fsck 检验
*/# 修改开机配置文件etc/fstab加入/dev/hdc6 /mnt/hdc6 ext3 defaults 1 2并卸载umount /dev/hdc6装置。最后能成功挂载
但实际上挂载是记录到 /etc/mtab ,/proc/mounts 这两个档案
*/# 如果以上错误了可以用单人模式执行以下命令,当你进入单人维护模式时,你的根目目录会被系统挂载为只读,
根目录根本就不能够被卸除的,只能重新挂载
fdisk -l */# 查看挂载装置即磁盘
mount -o remount,rw,auto /
umount /dev/hdc6 */# 用装置文件名来卸除
umount /media/cdrom */# 用挂载点来卸除
umount /mnt/flash */# 因为挂载点比较好记忆!
umount /dev/fd0 */# 用装置文件名较好记!
umount /mnt/home */# 一定要用挂载点!因为挂载的是目录
*/# 特殊装置 loop 挂载(映象档不刻录就挂载使用)
mkdir /mnt/centos_dvd */# 用loop挂载iso映像文件
mount -o loop /root/centos5.2_x86_64.iso /mnt/centos_dvd
ll /mnt/centos_dvd */# 查看iso里的数据
umount /mnt/centos_dvd/ */# 使用完卸载
*/#系统的分割不良解决办法:可以制作大档案然后格式化用loop挂载,制作分割槽
dd if=/dev/zero of=/home/loopdev bs=1M count=512 建立大空档案
mkfs -t ext3 /home/loopdev 格式化
mount -o loop /home/loopdev /media/cdrom/ 挂载
*/# 内存置换空间(swap)的建置:
使用实体分割槽建置 swap,使用档案建置 swap
fdisk /dev/hdc */# 磁盘中分给 swap ,也可用dd if=/dev/zero of=/tmp/swap bs=1M count=128档案建立swap
partprobe
mkswap /dev/hdc7 */# 开始建置 swap 格式,『mkswap 装置文件名』
free */# swap 使用上的限制
total used free shared buffers cached
Mem: 742664 684592 58072 0 43820 497144 */# 有 742664K 的物理内存,使用 684592K 剩余 58072K ,
43820K / 497144K 用在缓冲/快取的用途中
-/+ buffers/cache: 143628 599036
Swap: 1020088 96 1019992 */# 至于swap 已经存在了 1020088K
swapon /dev/hdc7 */# 将该 swap 装置启动,方法为:『swapon 装置文件名』
swapon -s */# 列出目前的swap有哪些
swapoff /tmp/swap
swapoff /dev/hdc7 */#使用 swapoff 关掉 swap file
磁盘参数修订: mknod, e2label, tune2fs, hdparm
装置以档案代表,档案怎么代表装置?
brw-r----- 1 root disk 22, 4 Oct 24 16:02 /dev/hdc4 档案的 major=22,minor=4 数值
mknod /dev/hdc10 b 22 10 建立装置/dev/hdc10 装置代码 22, 10
mknod /tmp/testpipe p 建立一个 FIFO 档案,档名为 /tmp/testpipe
磁盘空间浪费问题
-----------Linux 系统常见的压缩指令,备份和还原----------
*/# 扩展名大多是:『*.tar, *.tar.gz, *.tgz, *.gz, *.Z, *.bz2』
*.Z compress 程序压缩的档案;
compress -v man.config 压缩,源文件会不见 , uncompress man.config.Z解压缩
compress -c man.config > man.config.back.Z 压缩成另外一个档案用以备份
compress 无法解开 *.gz 的档案,而 gzip 则可以解开
*.Z 的档案
*.gz gzip 程序压缩的档案;
gzip -v man.conf,压缩文件可被WinRAR 这个软件解压,源文件会不见
gzip -9 -c man.config > man.config.gz 保留源文件的并用最好的压缩比
zcat man.config.gz 读这个压缩文件
gzip -d man.config.gz 解压缩这个文件
*.bz2 bzip2 程序压缩的档案; 作为压缩与解压缩文件用的
bzip2 -z man.config 提供比gzip更好的压缩比
bzcat man.config.bz2 读出档案内容
bzip2 -d man.config.bz2 解压缩档案(b可用unzip2 取代 bzip2 -d )
bzip2 -9 -c man.config > man.config.bz2 保留源文件并用最好的压缩比
*.tar tar 程序打包的数据,并没有压缩过;
*.tar.gz tar 程序打包的档案,其中并且经过 gzip 的压缩
*.tar.bz2 tar 程序打包的档案,其中并且经过 bzip2 的压缩
tar是将不同档案和目录打包为大档案,并且用bzip2/gzip分别压缩所有档案
压 缩:tar -jcv -f filename.tar.bz2 要被压缩的档案或目录名称
tar -zpcv -f /root/etc.tar.gz /etc 备份 p为保留权限与属性
tar -jpcv -f /root/etc.tar.bz2 /etc 备份
查 询:tar -jtv -f filename.tar.bz2
解压缩:tar -jxv -f filename.tar.bz2 -C 欲解压缩的目录
tar -jpPcv -f /root/etc.and.root.tar.bz2 /etc 备份的时候,-P是加上了根目录会覆盖危险,最好不加-P
tar -jtv -f /root/etc.tar.bz2 | grep ‘shadow‘ 解压打包文件中的单一文件,先查看
tar -jxv -f /root/etc.tar.bz2 etc/shadow 解开单一档案
tar -jcv -f /root/system.tar.bz2 --exclude=/root/etc* --exclude=/root/system.tar.bz2 /etc /root */# 不包含某些文件和自身的打包
tar -jcv -f /root/etc.newer.then.passwd.tar.bz2 --newer-mtime="2008/09/29" /etc/* */# 仅备份比某个时刻还要新的档案
tar -jtv -f /root/etc.newer.then.passwd.tar.bz2 | grep -v ‘/$‘ */# 打包结尾不是/的档名
tar -cvf - /etc | tar -xvf - 将档案一边打包一边在/tmp下解打包,类似cp -r的管线命令
*/# 完整备份工具:
dump, 可以使用用挂载点和装置文件名进行文件系统的备份0-9个level,用也无法建立
也可以给单个各别目录做完整备份1个level,但-u不能 /etc/dumpdates 这个各别 level 备份的时间记录文件
dump -S /dev/hdc1 测试需要多少容量才能备份
dump -0u -f /root/boot.dump /boot 将完整备份的文件名记录成为 /root/boot.dump ,同时更新记录文件
dump -0u -f /root/boot.dump /boot 完整备份,并更新记录文件
cat /etc/dumpdates 观察以上记录文件的ctime时间
dump -W 查看是否曾经备份过的档案
dd if=/dev/zero of=/boot/testing.img bs=1M count=10 在刚备份的挂载点下建立10M的大档案
dump -1u -f /root/boot.dump.1 /boot 建立差异备份档
dump -0j -f /root/etc.dump.bz2 /etc 使用 level 0的完整备份将 /etc 给dump,且含压缩功能(-j)
restore -t -f /root/boot.dump 观察dump后的备份数据内容
restore -t -f /root/etc.dump 显示出的是文件名与源文件的inode 状态
restore -C -f /root/boot.dump 看使进行文件系统与备份文件之间的差异!
restore -r -f /root/boot.dump 将备份文件中的数据还原到挂载点所在的那个目录下
restore -i -f /root/etc.dump 互动模式,help,根据提示解压缩部分档案
*/# 其他常见的压缩与备份工具
光盘写入工具
先将所需要备份的数据建置成为一个映像档(iso),利用 mkisofs 建立映像档,光盘格式一般称为 iso9660
将该映像文件刻录至光盘或 DVD 当中,利用 cdrecord 光盘刻录工具
mkisofs -r -v -o /tmp/system.img /root /home /etc */# 建立映像档
mount -o loop /tmp/system.img /mnt */# 挂载这个装置
df -h
ls /mnt 通过挂载点查看
mkisofs -r -V ‘linux_file‘ -o /tmp/system.img \ */# 此时备份成iso文件的时候会分别装在目录中 -graft-point
> -m /home/lost+found -graft-point /root=/root /home=/home /etc=/etc */# -m是排除这个档案的作用
cdrecord: */# 光盘刻录工具
cdrecord -scanbus dev=ATA */# 查刻录机 将 /tmp/system.img 刻录到 CD/DVD
*/# dd 用以备份 可以读取磁盘装置的内容(几乎是直接读取扇区"sector"),然后将整个装置备份成一个档案
dd if=/etc/passwd of=/tmp/passwd.back */# 将/etc/passwd 备份到 /tmp/passwd.back 当中
dd if=/dev/hdc of=/tmp/mbr.back bs=512 count=1 */# 将自己的磁盘第一个扇区备份,第一个扇区内有 MBR, partition table分区表同时得到备份
还原呢?就反向回去!
*/# dd if=/tmp/boot.whole.disk of=/dev/hdc1
*/# diff 档案比对工具: diff纯文档对比, 借由diff建立的分析档
cat /etc/passwd | sed -e ‘4d‘ -e ‘6c no six line‘ > passwd.new */# 将第四行删除,第六行则取代成为no six line
diff passwd.old passwd.new */# 此对比新旧档案
diff /etc/rc3.d/ /etc/rc5.d/ */# 开机执行等级(runlevel) 等级 3 与 5的启动脚本分别放置到 /etc/rc3.d 及/etc/rc5.d 互相对比
*/# cmp 非纯文档对比, 用字节进行对比
cmp passwd.old passwd.new
*/# patch处理补丁功能的档案,先比较先旧版本的差异,将差异档制作成为补丁档,再由补丁档更新旧档案
diff 制作出的比较档案通常使用扩展名为 .patch , -p0 是两个档案在同一个目录不需要diff 旧目录 新目录(依据建立patch档案所在目录来进行目录的删减)
diff -Naur passwd.old passwd.new > passwd.patch */# 更新
patch -pN < patch_file */# 还原
patch -R -pN < patch_file
patch file */# 用来更新旧版数据
patch -p0 < passwd.patch
patch -R -p0 < passwd.patch */# 恢复旧档案的内容
*/# 与文件系统及程序的限制关系: ulimit 限制用户的自由包括开启的档案数,CPU时间,内存总量
ulimit -a 列出所有限制资料数值
ulimit -f 10240 限制用户仅能建立 10MBytes 以下的容量的档案
ulimit -a
dd if=/dev/zero of=123 bs=1M count=20 此时用这个建立20M的档案会失败
*/# tar 可以用来备份关键数据,而 dd 则可以用来备份整颗 partition或整颗 disk
dd if=/dev/hdc1 of=/tmp/boot.whole.disk
*/# cpio 备份包括装置设备 配合find
find /boot -print */# 找到 /boot 底下应该要存在的档名与目录
find /boot | cpio -ocvB > /tmp/boot.cpio */# find /boot 可以找出档名通过管线命令传给cpio
备份:find / | cpio -ocvB > /dev/st0
还原:cpio -idvc < /dev/st0
ll -h /tmp/boot.cpio
*/-------filesystem文件系统的 inode, block 还有 superblock --------------
*/# 如何制作文件系统,包括分割、格式化与挂载
MBR开机启动与分割表都在第一个扇区,分割表用于记录分区所在的开始与结束的磁柱范围。
分区后格式化就格式为操作系统能够用的文件系统,win2000前是 FAT (或FAT16),win2000后是NTFS 文件
linux是Ext3,Ext2,一个文件系统就是一个分区。 LVM 与软件磁盘阵列(software raid)将一个分割槽格式化为多个文件系统(例如 LVM)
也能够将多个分割槽合成一个文件系统(LVM, RAID)在格式化时已经不再说成针对 partition 来格式化了,而称呼一个可被挂载的数据为一个文件系统而不是一个分割槽了
*/# 当写入的数据仅有 inode table 及 data block 而已,其他数据如:同步更新 inode bitmap, block bitmap,和更新
superblock 的内容并未保持一致而忽然断电了,则由查看 Superblock 当中记录的 valid bit (是否有挂载)与 filesystem state (clean 与否) 等
状态来判断是否强制进行数据一致性的检查。或者使用 e2fsck 这支程序检查针对 metadata 区域与实际数据存放区来比对,不过这样太费时间,通过以下方式:
*/# 日志式文件系统的功能:标准文件系统Ext2,日志文件系统Ext3,包括 SGI 的 XFS 文件系统,小型档案的Reiserfs 文件系统,Windows的 FAT 文件系统
传统文件系统:ext2 / minix / MS-DOS / FAT (用 vfat 模块) / iso9660 (光盘)等等;
日志式文件系统: ext3 / ReiserFS / Windows‘ NTFS / IBM‘s JFS / SGI‘s XFS
网络文件系统: NFS / SMBFS
1. 预备:当系统要写入一个档案时,会先在日志记录区块中记录某个档案准备要写入的信息;
2. 实际写入:开始写入档案的权限与数据;开始更新 metadata 的数据;
3. 结束:完成数据与metadata的更新后,在日志记录区块当中完成该档案的记录
*/# FAT 文件系统:没有 inode 存在,所有 block 在一开始就读出来
*/# 索引式文件系统:如果能够找到档案的inode就会知道这个档案所放置的block 号码,也就能够读出该档案了
Ext2 是索引式文件系统, (block group) 每个区块群组都有独立的inode/block/superblock 系统
Linux 的 EXT2 文件系统(inode): data block, inode table, superblock, dumpe2fs
block group :
1.superblock:记录此 filesystem 的整体信息,包括 inode/block 的总量、使用量、剩余量,文件系统的格式的相关信息等;
block 和inode 的大小 (block 为 1, 2, 4K,inode 为 128 bytes);
filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck)的时间
若此文件系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为1
以 dumpe2fs 指令呼叫,superblock 的大小为1024bytes
2.inode table:记录档案的属性,一个档案占用一个 inode,同时记录此档案的数据所在的 block 号码;
inode 仅有 12个直接指向。其他多重指向block。inode 本身不会记录文件名,文件名的记录是在目录的 block 当中
该档案的存取模式(read/write/excute);
该档案的拥有者与群组(owner/group);
该档案的容量;
该档案建立或状态改发的时间(ctime);
最近一次的读取时间(atime);
最近修改的时间(mtime);
档案特性的(flag),如 SetUID...;
该档案真正内容的指向(pointer);
每个 inode 大小均固定为 128 bytes;
每个档案都仅会占用一个 inode 而已;
文件系统能够建立的档案数量与inode的数量有关
系统读档案时需要先找到 inode,并分析 inode 所记录的权限与用户是否符合,
若符合才能开始实际读block内容
3.data block:实际记录档案的内容,若档案太大时,会占用多个 block
支持的block 大小有 1K, 2K 及 4K
每个 block 内最多只能够放置一个档案的数据
每个 block 都有编号,以方便 inode记录
除非重新格式化(或利用resize2fs 等指令变更文件系统大小),否则 inode与block 固定后就不再变动
4.Filesystem Description (文件系统描述说明)
区段,记录block group开始结束的block 号码,
记录(superblock,bitmap, inodemap, data block) 分别介于哪一个 block 号码之间
也能够用 dumpe2fs 查
5.block bitmap (区块对照表) 当中可以知道哪些 block 号码是空的
6.inode bitmap (inode对照表) 当中可以知道哪些 inode 号码是空的
*/# 文件系统通帯会将Linux 操作系统的档案权限(rwx)与文件属性(拥有者、群组、时间参数等)分别存放在不同的区块,
权限放置到 inode中,实际数据放置到 data block 区块中。
inode 记该目录的相关权限与属性,以及内容放哪个block.
一个 inode 与至少一块 block ,block 记在这个目录下的文件名与该文件名占用的 inode 号码数据,
*/# 目录树读取
ll -di / /etc /etc/passwd
2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /
1912545 drwxr-xr-x 105 root root 12288 Oct 14 04:02 /etc
1914888 -rw-r--r-- 1 root root 1945 Sep 29 02:21 /etc/passwd
读取流程:先找到挂载点的inode由2号开始,读取根目录的block内的文件名数据,一层层读到正确档名
一般使用者读取流程:
1. / 的 inode:
透过挂载点的信息找到 /dev/hdc2 的 inode 号码为 2 的根目录 inode,且 inode 规范的权限读该 block 的内容(有 r 不 x) ;
2. / 的 block:
得 block 的号码找到该内容有 etc/ 目录的 inode 号码 (1912545);
3. etc/ 的 inode:
读取1912545 号 inode 得知 vbird 具有 r x 的权限,因此可以读取etc/ 的 block 内容;
4. etc/ 的 block:
得 block 号码,找到该内容有 passwd 档案的 inode 号码 (1914888);
5. passwd 的 inode:
读取1914888 号 inode 得知 vbird 具有 r 的权限,可读取passwd 的 block 内容;
6. passwd 的 block:
最后将该 block 内容的数据读出来。
boot sector 与 superblock 的关系
*/----- Linux 目录档案的 ls, pwd, cd, cp, mv, rm, mkdir, touch, cat, more, less, head, tail ,od, basename, dirname ------
[ l ]连结档
[ d ]则是目录,
[ - ]则是档案,档案分:
纯文本档(ASCII),可以用cat读出 ,二进制文件(binary)可执行文件(scripts, 文字型批处理文件不算)
数据格式文件(data)
使用者登入时,都会将登录的数据记录在 /var/log/wtmp 那个档案内,该档案是一个 data file,
他能够透过 last 读出来,cat则会乱码。[ l ]则表示为连结档(link file)快捷方式[lrwxrwxrwx] ,
[ b ]则表示为装置文件,集中在/dev 这个目录下
[ c ]则表示为装置文件里面的串行端口设备,特色就是『一次性读取』不可截断
[ s ]资料接口文件(sockets)通常被用在网络上的数据承接,最常在/var/run 这个目录中
[ p ] 数据输送文件(FIFO, pipe)
pwd */# 显示出目录
/var/mail */# 列出目前的工作目录
pwd -P
/var/spool/mail */# -P显示出真实的路径
cd ~ */# 回到自己的家目录
cd - */# 回到刚刚的家
cp */# 复制,建立连接档,
cp ~/.bashrc /tmp/bashrc
cp -i ~/.bashrc /tmp/bashrc */# 覆盖前询问
cp /var/log/wtmp . */# 复制到当前目录下 ,权限会变
cp -a /var/log/wtmp wtmp_2 */# 建立连接档并将档案的所有特性都一起复制
cp -a /var/log/wtmp /tmp/vbird_wtmp */# 完整复制档案到目录下,此命令只能用于root,一般用户仅仅能复制权限和时间,并不能复制拥有者和群组。
-rw-rw-r-- 1 vbird vbird 96384 9 月 24 11:54 /tmp/vbird_wtmp
-rw-rw-r-- 1 root utmp 96384 9 月 24 11:54 /var/log/wtmp
cp -r /etc/ /tmp */# 目录要复制得加-r ,权限会变
cp -a /etc /tmp */# 带权限的复制目录,用以备份
cp -u ~/.bashrc /tmp/bashrc */# 有差异才复制过来,用以备份
cp ~/.bashrc ~/.bash_history /tmp 批量复制到目录
挂载点--访问目录--根据文件名找到对应的block,存储的inode号码判断是否有权限---有权限则指向实际block的内容。
实体链接与符号链接:每个档案都会占用一个 inode ,档案内容由 inode 的记录来指向;想要读取该档案,必项要经过目录记录的文件名来指向到正确的inode,
通过多个档名对应一个inode则为实体链接,目录的link 数量会随着档案连接而增加。如在tmp目录下建立文件夹,它的连接数加1 了。
每个档名连结到一个 i-node(每个档案都会将他的权限与属性记录到文件系统的 i-node 中,
目录树却是使用文件名来记录,连接数记录有多少不同的档名连接到同一个i-node号码)
ln /etc/crontab . */# 建立实体链接的指令,磁盘的空间与inode的数目都不会改。只是在某个目录下的 block 多写入一个关连数据而已
ll -i /etc/crontab /root/crontab
1912701 -rw-r--r-- 2 root root 255 Jan 6 2007 /etc/crontab
1912701 -rw-r--r-- 2 root root 255 Jan 6 2007 /root/crontab 当建立了实体链接后,连接数由1变2
cp -s ~/.bashrc bashrc_slink */# 复制成为『快捷方式』会连结到源文件(实体链接涉及 i-node )
cp -d bashrc_slink bashrc_slink_2 */# 复制连接档,将新的连接档连接旧的连接档连接的那个源文件
lrwxrwxrwx 1 root root 6 Sep 24 14:33 bashrc_slink_2 -> bashrc */# 是连结档!
ln -s /bin /root/bin 连接档,则访问/root/bin删掉其中数据的时候也会连带删掉真实数据,慎用。
快捷方式ln -s并不像连接档删掉了通过另个连接档依然能访问同一个inode指向的block文件内容。快捷方式对应的只是文件名称找到另个连接档,通过另个连接档对应的inode
到block实际内容。删掉了则无法访问
mv 移动 ,
mv bashrc mvtest 移动档案到目录
mv mvtest mvtest2 */# 更名了,批量更名用rename
mv bashrc1 bashrc2 mvtest2 批量移动档案到目录
rm 删除,
rm -i bashrc 删除前询问
rm -i bashrc* 删除前缀为bashrc的文件
rm -r test 干掉所有的目录及文件,(alias 的设定使得默认加入-i的选项,反斜杠去除alias)
\rm -r /tmp/etc 加入反斜杠后,可以忽略掉 alias 的设定选项
rm ./-aaa- 删除特殊文件,『 rm -- -aaa- 』也可以
rmdir: 删除一个空的目录
rmdir -p test1/test2/test3/test4 一次删除test1/test2/test3/test4,rmdir 仅能『删除空的目录』
mkdir: 建立一个新的目录
mkdir -p test1/test2/test3/test4 建立多层目录
mkdir -m 711 test2 建立权限为 rwx--x--x 的目录
建立文件都有默认权限由预设权限 (umask)设定
检视档案内容: cat, 由第一行开始显示档案内容
cat -n /etc/issue 查看系统版本
cat -b /etc/issue 不想要空白行的行号
cat -A /etc/xinetd.conf 内容完整的显示,包含特殊字符,[tab]会以 ^I 表示,断行字符则是以 $ 表示
tac, 从最后一行开始显示,可以看出 tac 是 cat 的倒着写!
nl 显示的时候,顺道输出行号!
nl /etc/issue 空白行不会加行号
nl -b a /etc/issue 空白行加行号
nl -b a -n rz /etc/issue 自动行号补上 0,默认行号为6位数
nl -b a -n rz -w 3 /etc/issue 自动行号补上 0,默认行号改3位数
可翻页检视: more, 一页一页的显示档案内容
more /etc/man.config :f :立刻显示出文件名以及目前显示的行数;
less 与more 类似,但是比 more 更好的是,他可以往前翻页
资料撷取: head, 只看头几行
head /etc/man.config 默认显示10行
head -n 20 /etc/man.config 显示前 20 行
head -n -100 /etc/man.config 共140页则,负数会列出前40页
head -n 20 /etc/man.config | tail -n 10 显示第11到20行数据。
tail 只看尾几行
tail -n 20 /etc/man.config 默认显示10行,这里显示前 20 行
tail -n +100 /etc/man.config 显示100行以后的数据
tail -f /var/log/messages 一直在监测状态,直到输入[crtl]-c
非纯文本档: od 以二进制的方式读取档案内容,可以将 data file , binary file 的内容读出
od -t c /usr/bin/passwd/usr/bin/passwd 这个执行档用 ASCII 方式查看
od -t oCc /etc/issue 以 8 进位列出
修改档案时间与建置新档: touch 建立的时候三个时间 (atime/ctime/mtime)都会更新到当前
即使我们复制一个档案时,复制所有的属性,但也没有办法复制 ctime 这个属性的
touch ./-aaa- 建立一个空档案
touch -d "2 days ago" bashrc 将日期调整为两天前,ctime不会改变
touch -t 0709150202 bashrc 将日期调整改为 2007/09/15 2:02,ctime不会改变
basename /etc/sysconfig/network network */# 取得完整文件的档名
dirname /etc/sysconfig/network /etc/sysconfig */#取得完整文件的目录名
ls -ld /var/mail */# /var/mail 是一个连结档
lrwxrwxrwx 1 root root 10 Sep 4 17:54 /var/mail -> spool/mail
ll -s
total 104 */# total是所耗用的实际 block 数量 * block 大小的值。
8 -rw------- 1 root root 1474 Sep 4 18:27 anaconda-ks.cfg
ls -l /etc/man.config
*/# mtime内容变更的时间
*/# ctime权限与属性的状态变更的时间
*/# atime被读取的时间
ls -l --time=atime /etc/man.config
ls -l --time=ctime /etc/man.config
ll bashrc; ll --time=atime bashrc; ll --time=ctime
ls -al ~ */# 含属性和隐藏文件
ls -alF --color=never ~ */# 文件名末显示出该文件名代表的类型
ls -al --full-time ~ */# 完整的呈现档案的修改时间
ls -al */# 仅列出目前短格式的时间
ls -l */# 与ll一样(那个功能是 Bash shell 的 alias 功能)
ls -i */# 查看档案的i-node号码,与权限、属性有关的数据放在 i-node 里面
ls -l --full-time */# 就能够显示出完整的时间格式了!
ls -al */# 列出所有的档案详细权限与属性包括隐藏文件(即.文件)
-rw -r- -r-- 1 root root 24 2007-01-06 .bash_logout
拥有者权限 群权限 other权限 连接数 拥有者 群 档案容量 最后修改时间 档名
*/-------权限chgrp, chown, chmod,档案默认权限umask,档案隐藏权限chattr,档案特殊权限SUID.SGID,观察文件类型file,
脚本文件名的搜寻which,档案档名的搜寻:whereis, locate, find ------
权限与指令间的关系:
*/# vbird 能够进行『cp /dir1/file1 /dir2』读取源文件,并写入目标文件的最小权限是
dir1 :至少需要有 x 权限;
file1:至少需要有 r 权限;
dir2 :至少需要有 w, x 权限
*/# 权限如下:
drwxr-xr-- 1 test1 testgroup 5238 Jun 19 10:25 groups/ */# test2, test3 可本目录进行工作但不能写,
*/# other 的权限中[r--]虽然有 r ,但没x的权限不能进此目录!
*/# r可以查询此目目录下的文件名列表,无法到该目录下读取档案
*/# 权限如下:
-rwx------ 1 root root 4365 Sep 19 23:20 the_root.data */# 账号为 dmtsai,他的家目录在/home/dmtsai/,dmtsai 对此目录具有[rwx]的权限。
*/# dmtsai对此文件没权限,但家目录他具有rwx权限,此文件在他的家目录下,所以他可删除此档案。
*/# 所有人都可以工作的/tmp 目录下,建立testing/testing,当vbird用户对testing有w权限的时候,就可以删掉testing/testing
改变文件属性与权限: chgrp, chown, chmod
[-][rwx][r-x][r--]
1 234 567 890
1 为: 代表这个文件名为目录或档案,本例中为档案(-);
234 为:拥有者的权限,本例中为可读、可写、可执行(rwx);
567 为:同群组用户权力,本例中为可读可执行(rx);
890 为:其他用户权力,本例中为可读(r)
r:4
w:2 w不包含删除该档案权限
x:1
chgrp :改变档案所属群组
chgrp -R users dirname */# 递归改变群组
chown :改变档案拥有者
chown bin install.log */# 改变档案拥有者
chown root:root install.log */# 顺便直接修改群组
chown .sshd install.log */# 也能单纯的修改所属群组
chmod 777 .bashrc */# 赋权限-rwxrwxrwx
cp ~/.bashrc ~dmtsai/bashrc
chown dmtsai:users ~dmtsai/bashrc */# root将文件复制后并授权一般用户
chmod :改变档案的权限, SUID, SGID, SBIT 等等的特长
chmod u/g/o/a +/-/= r/w/x 档案或目录 */# a 则代表 all 亦即全部的身份
*/# 在/etc/passwd这个档案中有记录的用户名称才能改变
*/# 需要使用 root 的身份才能够处理
chmod u=rwx,go=rx .bashrc */# 赋权限-rwxr-xr-x
chmod a+w .bashrc */# 批量给不同身份赋权,适用于不知道原本权限的情况
mkdir /tmp/chapter7_1
chown -R dmtsai:users /tmp/chapter7_1
chmod -R 755 /tmp/chapter7_1 */# root给一般授权并让其他人能进入查看
档案默认权限:umask */# umask指的是建立档案或目录时候的权限默认值需要减掉的权限! 可以参考环境参数配置文件 /etc/bashrc 这个档案的内容
umask */# 默认拿掉了写w的权限
0022 */# 看到数字形态的权限设定分数,与一般权限有关的是后面三个数字!
umask -S
u=rwx,g=rx,o=rx */# 以符号类型的权限设定分数,第一组是特殊权限
一般建档没有可执行( x )权限:666即-rw-rw-rw- 则 - (-----w--w-) ==> -rw-r--r-- 644
一般目录所有权限均开放:777 即drwxrwxrwx 则 - (d----w--w-) ==> drwxr-xr-x 755
-rw-r--r-- 1 root root 0 Sep 27 00:25 test1 新建档案的权限
drwxr-xr-x 2 root root 4096 Sep 27 00:25 test2 新建目录的权限
umask 002 如果要让同组的人开放写w的权限,就不能只是644权限,所以umask就不能拿掉 2这个w权限,修改umask
架设文件服务器 (file server) -- SAMBA Server 或 FTP server对于新建档案与目录权限方面用umask
档案隐藏权限:chattr 设置,lsattr 查看 */# 设定除 r, w, x 权限外的其他的系统隐藏属性,
在安全机制上面可以设置不可修改的特性,让连档案的拥有者都不能进行修改
chattr +i attrtest */# 设置档案attrtest不能被删除,i 让一个档案无法被更动
chattr -i attrtest */# 取消不能被删除的隐藏属性
chattr +a attrtest */# 设置只能增加不能修改旧有的数据不删除的参数(log file登录档和/etc/shadow 密码记录等档案的设置)
chattr +aij attrtest
lsattr attrtest */# 查阅
档案特殊权限:SUID.SGID */# 当 s 标志在档案拥有者的 x 项目为 SUID,那 s 在群组的 x 时则称为 Set GID
SUID, Set UID */# 仅对二进制,执行者有具有 x 权限且在执行过程中,执行者有(owner)的权限,
ls -ld /tmp ; ls -l /usr/bin/passwd */# /tmp 和/usr/bin/passwd 权限都有特殊权限( s 跟 t )
drwxrwxrwt 7 root root 4096 Sep 27 18:23 /tmp
-rwsr-xr-x 1 root root 22984 Jan 7 2007 /usr/bin/passwd */# SUID 的特殊权限(一般用户当然可以修改自己的密码,root是所有者)
1. vbird对/usr/bin/passwd 的可以执行x权限,执行 passwd;
2. passwd 的拥有者是 root 这个账号;
3. vbird 执行 passwd 的过程中,会暂获root权限;
4. 账号的密码都记录在 /etc/shadow 这个权限为:『-r-------- 1 root root』的档案中,仅有root可读且仅有root可强制写
4. /etc/shadow 就可以被 vbird 所执行的 passwd 所修改。
SGID, Set GID */# 仅对二进制,执行者有具有 x 权限且在执行过程中,执行者有(group) 的权限,
ls -l /usr/bin/locate */# 使用vbird这个账号去执行 locate 时,vbird 将会取得 slocate 群组的支持,因此就能够去读取 mlocate.db
-rwx--s--x 1 root slocate 23856 Mar 15 2007 /usr/bin/locate
ll /usr/bin/locate /var/lib/mlocate/mlocate.db
-rwx--s--x 1 root slocate 23856 Mar 15 2007 /usr/bin/locate
-rw-r----- 1 root slocate 3175776 Sep 28 04:02 /var/lib/mlocate/mlocate.db
SGID 用在目录上,一个目录设定了 SGID 的权限后。用户对目录r,x的权限时,进入此目录;用户在此目录下的有效群组(effective group)将会变成该目录的群组;
用途:若群组有w权限,则用户在此目录下具有 w 的权限(可以新建档案),使该新档案的群组为目录的群组
SBIT, */# 只针对目录有效,档案无效。
1.当用户对于此目录具有 w, x 权限,亦即具有写入的权限时;
2.当用户在该目录下建立档案或目录时,仅有自己与 root 才有权力删除该档案
/tmp 本身的权限是『drwxrwxrwt』, 在这样的权限内容下,任何人都可以在
/tmp 内新增、修改档案,但仅有该档案/目录建立者与 root 能够删除自己的目录或档案
赋予特殊权限:
4 为 SUID SUID u+s
2 为 SGID SGID g+s
1 为 SBIT SBIT o+t
cd /tmp */# tmp用户执行以下命令
touch test */# 建立一个测试用空档
chmod 4755 test; ls -l test */# 加入具有 SUID 的权限
-rwsr-xr-x 1 root root 0 Sep 29 03:06 test
chmod 6755 test; ls -l test */# 加入具有 SUID/SGID 的权限
-rwsr-sr-x 1 root root 0 Sep 29 03:06 test
chmod 1755 test; ls -l test */# 加入 SBIT 的功能!
-rwxr-xr-t 1 root root 0 Sep 29 03:06 test
chmod 7666 test; ls -l test */# 具有空的 SUID/SGID 权限,因为没有执行权限。
-rwSrwSrwT 1 root root 0 Sep 29 03:06 test
chmod u=rwxs,go=x test; ls -l test */# 设定权限成为 -rws--x--x 的模样:
-rws--x--x 1 root root 0 Aug 18 23:47 test
chmod g+s,o+t test; ls -l test */# 承上,加上 SGID 与 SBIT 在上述的档案权限中!
-rws--s--t 1 root root 0 Aug 18 23:47 test
find /sbin -perm +7000 | ls -l 不好使,列有root所在目录下的档案,因为ll (ls)并不是管线命令
find /sbin -perm +7000 | xargs ls -l 透过 xargs 提供ls以引用 standard input之用
观察文件类型:file
file ~/.bashrc 属于 ASCII或者是 data档案,或是 binary
file /usr/bin/passwd 执行文件的数据包括这个档案的suid 权限、兼容于Intel386等级的硬件平台、使用的是 Linux 核心 2.6.9 的动态函式库链接等等
指令与档案的搜索:
脚本文件名的搜寻:which */# which 预设是找 PATH 内所有范围的目录
which ifconfig */# 用 root搜寻 ifconfig这个指令的完整文件名,一般帐号找不到因为 /sbin不在vbird的PATH中,
which which 一个是 alias『命令别名』
which cd 提示没有,cd 是『bash 内建的指令』可以透过 type 查
档案档名的搜寻:whereis, locate, find
whereis,locate */# Linux将系统内的所有档案都记在已建立的/var/lib/mlocate/数据库里,
*/# 以此为准,速度会比find快。更新 locate 数据库用updatedb
whereis ifconfig */# which找不到whereis能找到,因为系统真的有 ifconfig,但是使用者的path没有
whereis -m passwd */# 与passwd有关的说明文件档
locate passwd */# 找出系统中所有与passwd相关的档名,完整文件名只要包含 passwd就显示
updatedb: */# 根据 /etc/updatedb.conf的设定去搜寻系统硬盘内的文件名,并更新/var/lib/mlocate 内的数据库档案;
locate: */# 依据 /var/lib/mlocate内的数据库记载,找出用户输入的关键词文件名。
find / -mtime 0 */# 系统上面 24 小时内有更动过内容 (mtime)的档案,0是从现在开始到 24 小时前
find / -mtime 3 */# 三天前的 24 小时内有变动过
find /var -mtime 4 */# 四天前一天变更过内容
+4 代表大于等于 5 天前的档名:ex> find /var -mtime +4
-4 代表小于等于 4 天内的档案档名:ex> find /var -mtime -4
4 则是代表 4-5 那一天的档案档名:ex> find /var -mtime
find /etc -newer /etc/passwd /etc 底下日期比 /etc/passwd 新就列出
find /home -user vbird 找出home下vbird所有的档案。此命令可以找出任何一个用户在系统中的所有档案
find / -nouser 搜寻系统中不属于任何人的档案
find / -name passwd 找出档名为 passwd 这个档案
find /etc -name ‘*httpd*‘ 利用通配符寻找档名
find /var -type s 找出 /var目录下,文件类型为Socket的档案
7000 表示要含有 ---s--s--t 的所有三个权限
find / -perm +7000 档案当中各有 SGID或SUID或SBIT属性的档案
find /bin /sbin -perm +6000 找出各有 SGID或SUID的档案
find / -perm +7000 -exec ls -l {} \; 将上个范例找到的档案使用 ls -l 列出,-exec后面的ls -l就是额外的指令
find / -size +1000k 找出系统中,大于1MB 的档案
find /etc -size +50k -a -size -60k -exec ls -l {} \; -a 是 and ,找出/etc下介于50K到60K的档案且将权限完整的列出
find /etc -size +50k -a ! -user root -exec ls -ld {} \;
find /etc -size +50k -a ! -user root -type f -exec ls -l {} \; 容量大于50K且档案所属人不是root的档
find /etc -size +1500k -o -size 0 -o 就是或 (or),容量大于1500K 以及容量等于0的档案
-------------Linux 账号管理与 ACL 权限设定-------------
*/# Linux 到底是如何辨别每一个使用者的?
先寻找/etc/passwd是否有账号,将对应ID 取出在/etc/group读出来(即用户ID(User ID ,简称 UID)与群组 ID (Group ID ,简称 GID))
再核对密码表,进入 /etc/shadow 里面找出对应的账号与UID。很多账号是系统账号,如bin, daemon, adm, nobody不要随意杀掉。
使用者账号:/etc/passwd 档案结构, /etc/shadow 档案结构
关于群组: /etc/group 档案结构, 有效与初始群组, groups, newgrp, /etc/gshadow
*/# Linux 的账号与群组
/etc/shadow */# (该档案是[ -rw------- ]) 记录所有用户个人的密码
head -n 1 /etc/shadow
root:$1$O46tWk15$v14Gp5gfoV6iL2UsmSEAm.:16591:0:99999:7:::
1 2 3 4 5 6 7 8 9
账号,密码,最近改动密码的日期(14126看不懂,日期 chage指令来看,或echo $(($(date --date="2008/09/04" +%s)/86400+1))
得到的也是14126),密码不可被更动的天数(0表示随时可以变更),密码需要重新变更天数。密码需要变更期限前的警告天数。
密码过期后的宽限时间,账号失效日期。保留。
/etc/passwd */# 记录系统上的所有帐号数据,密码为x,密码放到shadow里了,第二栏对应/etc/shadow,第三栏对应/etc/group。
使用者标识符: UID 与 GID
head -n 1 /etc/passwd
root:x:0:0:root:/root:/bin/bash
1 2 3 4 5 6 7
账号名,密码,UID,GID,用户信息栏(finger 癿功能时, 这个字段可以提供信息,后面的chfm指令),家目录,shell
UID 是 0 时,代表这个账号是系统管理员
UID 是 1~499 500 以下的数字给系统作为保留账号,这些系统账号通常是不可登入得才有/sbin/nologin 这个特殊的shell 存在。
系统账号又约略被区分为两种:
1~99:由 distributions 自行建立的系统账号;
100~499:若用户有系统账号需求时,可以使用的账号 UID。
500~65535 (可登入账号) 给一般使用者用的。目前的linux 核心 (2.6.x 版)已经可以支持到4294967295 (2^32-1) 这巨大的 UID 号码喔!
grep ‘dmtsai‘ /etc/passwd */# 查找帐号,UID是第三个与帐号对应
ll -d /home/dmtsai */# 查看权限,该家目录档案记录了UID和GID两个属性
/etc/group */# 所有的组名都记录其中 有效与初始群组、groups, newgrp
head -n 1 /etc/group
root:x:0:root
1 2 3 4
组名 密码 GID 此群组支持的账号名称(会吧同一个群组GID对应的账号都列出来)
*/# 有效群组与初始群组: 一个账号可以加入多个群组,到底以哪个群组为准看有效群组。
usermod -G users dmtsai */# 先设定好次要群组
grep dmtsai /etc/passwd /etc/group /etc/gshadow
/etc/passwd:dmtsai:x:503:504::/home/dmtsai:/bin/bash
/etc/group:users:x:100:dmtsai */# 次要群组的设定
/etc/group:dmtsai:x:504: */# 因为是初始群组,所以第四字段不需要填入账号
/etc/gshadow:users:::dmtsai */# 次要群组的设定
/etc/gshadow:dmtsai:!::
su dmtsai;
groups */# 用dmtsai登录,列出群组
dmtsai users */# 第一个为有效群组,可以切换
touch test
ll
-rw-rw-r-- 1 dmtsai dmtsai 0 Feb 24 17:26 test
newgrp users
groups */# 切换有效群组,newgrp提供新的shell给予有效的GID,exit回本shell
users dmtsai
touch test2
ll
-rw-rw-r-- 1 dmtsai dmtsai 0 Feb 24 17:26 test
-rw-r--r-- 1 dmtsai users 0 Feb 24 17:33 test2
*/# 加入群组的方式有两种:
系统管理员 (root)利用 usermod 加入,或群组管理员以 gpasswd加入群组中
/etc/gshadow */# gshadow 最大的功能就是建立群组管理员,类似 sudo 工具取代了
head -n 4 /etc/gshadow
root:::root
bin:::root,bin,daemon
daemon:::root,bin,daemon
sys:::root,bin,adm
1 23 4
1. 组名 2.密码栏,开头为 ! 表示无合法密码,所以无群组管理员
3. 群组管理员的账号 (相关信息在 gpasswd 中介绍)
4. 该群组的所属账号 (与 /etc/group 内容相同!)
useradd vbird1 */# 新增用户
ll -d /home/vbird1
drwx------ 4 vbird1 vbird1 4096 Feb 25 09:38 /home/vbird1 */# 默认建立用户家目录,且权限为 700
grep vbird1 /etc/passwd /etc/shadow /etc/group
/etc/passwd:vbird1:x:504:505::/home/vbird1:/bin/bash
/etc/shadow:vbird1:!!:14300:0:99999:7:::
/etc/group:vbird1:x:505: */# 会建立一个与账号一模一样的群组名
用户账号/密码相关参数:/etc/passwd, /etc/shadow
使用者群组相关参数:/etc/group, /etc/gshadow 档案的新增、修改与删除。加上有效群组的概念, newgrp 与 gpasswd 则不可不知。
用户个人档案数据: /home/username, /var/spool/mail/username.
新增与移除使用者: useradd, useradd 参考档, passwd, chage, usermod, userdel
useradd
在 /etc/passwd 里面建立一行与账号相关的数据,包括建立 UID/GID/家目录等
在 /etc/shadow 里面将此账号的密码相关参数填入,但是尚未有密码
在 /etc/group 里面加入一个与账号名称一模一样的组名
在 /home 底下建立一个与账号同名的目录作为用户家目录,且权限为 700
useradd -u 700 -g users vbird2 */# 用 users 这个以已存在的群组作为初始群组,
以及uid为700来建立一个名为vbird2的账号,并指定了特殊的 UID 来作为使用者的专属 UID
*/# 因为群组已经存在, 所以在 /etc/group 里面就不会主动的建立与账号同名的群组了。
useradd -r vbird3 */# 建立系统账号,加上 -r 这个选项以后,系统就会主动将账号与账号同名群组的UID/GID 都指定小于500 以下
ll -d /home/vbird3 */# 系统账号主要是运作系统所需服务的权限设定
ls: /home/vbird3: No such file or directory */# 不会主动建立家目录
grep vbird3 /etc/passwd /etc/shadow /etc/group
*/# 系统账号主要是用来进行运作系统所需服务的权限设定,所以系统账号默认都不会主动建立家目录的
/etc/passwd:vbird3:x:100:103::/home/vbird3:/bin/bash
/etc/shadow:vbird3:!!:14300::::::
/etc/group:vbird3:x:103
用户账号与密码参数方面的档案:/etc/passwd, /etc/shadow
使用者群组相关方面的档案:/etc/group, /etc/gshadow
用户的家目录:/home/账号名称
useradd( /etc/default/useradd) 默认
useradd -D
GROUP=100 */# 预设的群组
HOME=/home */# 默认得家目录所在目录
INACTIVE=-1 */# 密码失效日,在 shadow 内的第 7 栏
EXPIRE= */# 账号失效日,在 shadow 内的第 8 栏
SHELL=/bin/bash */# 预设的shell
SKEL=/etc/skel */# 用户家目录的内容数据参考目录
CREATE_MAIL_SPOOL=yes */# 是否主动帮使用者建立邮件信箱
GROUP=100 :GID 为 100 者是 users 这个群组,vbird1 的初始群组为 vbird1二不是users是因为 有RHEL, Fedora, CentOS这些
distributions私有群组机制,而代表 distributions 如 SuSE 等是公共群组机制。
SHELL=/bin/bash:若账号都要使用发件功能但不许用户登入系统取得 shell,可将SHELL=设定为/sbin/nologin, 免去后续使用 usermod进行修改
SKEL=/etc/skel:可以设定环境变量 ~/.bashrc使新增用户后会在家目录下建立某个文件
vi /etc/login.defs */# 此文件设定密码及新增UID的序列递增
grep ‘PASS_MAX_DAYS‘ /etc/login.defs
PASS_MAX_DAYS Maximum number of days a password may be used. */# PASS_MAX_DAYS
99999/etc/shadow 内每一行都会有『 0:99999:7 』存在
CREATE_HOME = yes 设定家目录, useradd 执行时-m表示设定家目录 ,umask 预设值为077,权限为drwx------
USERGROUPS_ENAB yes 用户删除时如果没有群组隶属于这个组的话就删掉这个群组。
MD5_CRYPT_ENAB yes 加密方式。
*/# useradd还会参考以下文件
/etc/default/useradd
/etc/login.defs
/etc/skel/*
passwd */# 修改密码
PAM 模块来进行密码的检验,这个管理的机制写在 /etc/pam.d/passwd 中,测试模块就是使用:pam_cracklib.so,
并且取代 /etc/login.defs 内的PASS_MIN_LEN的设定
echo "abc543CC" | passwd --stdin vbird2 */# 使用 standard input 建立用户的密码
Changing password for user vbird2.
passwd: all authentication tokens updated successfully.
passwd -S vbird2
vbird2 PS 2009-02-26 0 99999 7 -1 (Password set, MD5 crypt.) */# 上面说明密码建立时间 (2009-02-26)、
0 最小天数、99999 变更天数、7 警告日数,密码不会失效 (-1) 。
passwd -x 60 -i 10 vbird2 */# 管理 vbird2的密码使具有 60 天变更、10 天密码失效的设定
passwd -S vbird2
vbird2 PS 2009-02-26 0 60 7 10 (Password set, MD5 crypt.)
passwd -l vbird2 */# 让 vbird2 的账号失效,观察完毕后再让她失效
passwd -S vbird2
vbird2 LK 2009-02-26 0 60 7 10 (Password locked.) */# LK, Lock无法登入喔!
grep vbird2 /etc/shadow
vbird2:!!$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10:: */# 只是在/etc/shadow加上 !!
passwd -u vbird2 */# 密码字段恢复正常!
grep vbird2 /etc/shadow
vbird2:$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10::
chage -l vbird2 */# 列出 vbird2 的详细密码参数
建立一个名为 agetest 的账号,该账号第一次登入后使用默认密码,但必须要更改过密码后,
使用新密码才能够登入系统使用 bash 环境。
useradd agetest
echo "agetest" | passwd --stdin agetest
chage -d 0 agetest */# 此时此账号的密码建立时间会被改为 1970/1/1 ,所以会有问题!
usermod
usermod -c "VBird‘s test" vbird2 */# usermod 也是用来微调 useradd 增加的使用者参数。
-L 与 -U 修改使用者 vbird2 的说明栏,加上VBird‘s test的说明。
grep vbird2 /etc/passwd
vbird2:x:700:100:VBird‘s test:/home/vbird2:/bin/bash
usermod -e "2009-12-31" vbird2 */# 用户 vbird2 密码在 2009/12/31 失效。
grep vbird2 /etc/shadow
vbird2:$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10:14609:
ll -d ~vbird3
ls: /home/vbird3: No such file or directory */# 确认一下,确实没有家目录的存在!
cp -a /etc/skel /home/vbird3
chown -R vbird3:vbird3 /home/vbird3 */# 使用 chown -R 是为了连同家目录底下的用户/群组属性都一起变更的意思
chmod 700 /home/vbird3 */# 使用 chmod 没有 -R ,是因为我们仅要修改目录的权限而非内部档案的权限!
ll -a ~vbird3
drwx------ 4 vbird3 vbird3 4096 Sep 4 18:15 . */# 用户家目录权限
userdel
find / -user username */# 查出整个系统内属于username的档案,然后再使用userdel
userdel -r vbird2 */# 初除 vbird2 ,连同家目录一起删除
用户功能:finger, chfn, chsh, id
finger */# 检查用户信息,列出基本都是/etc/passwd的东西
finger vbird1 */# 观察 vbird1的用户相关账号属性
Login:为使用者账号,亦即 /etc/passwd 内的第一字段;
Name:为全名,/etc/passwd 内的第五字段(或称为批注);
Directory:就是家目录了;
Shell:就是使用的 Shell 档案所在;
Never logged in.:figner 还会调查用户登入主机的情况喔!
No mail.:调查 /var/spool/mail 的信箱资料;
No Plan.:调查 ~vbird1/.plan 档案,将该档案取出来说明
echo "I will study Linux during this year." > ~/.plan */# 利用 vbird1 建立自己的计划档
finger vbird1
Login: vbird1 Name: (null)
Directory: /home/vbird1 Shell: /bin/bash
Never logged in.
No mail.
Plan:
I will study Linux during this year.
finger
Login Name Tty Idle Login Time Office Office Phone */# 找出目前在系统上面登入的用户与登入时间
root root tty1 Feb 26 09:53
vbird1 tty2 Feb 26 15:21
chfn */# vbird1 自己更改一下自己的相关信息!
chfn */# chfn 与 chsh ,都是能够一般用户修改 /etc/passwd 这个系统文件的,所以这两个档案的权限是SUID
Changing finger information for vbird1.
Password: */# 确认身份,所以输入自己的密码
Name []: VBird Tsai test */# 输入你想要呈现的全名
Office []: Dic in Ksu. Tainan */# 办公室号码
Office Phone []: 06-2727175 */#356 */# 办公室电话
Home Phone []: 06-1234567 */# 家里电话号码
Finger information changed.
grep vbird1 /etc/passwd */# 其实就是改到第五个字段,该字段里面用多个『 , 』分隔就是了!
vbird1:x:504:505:VBird Tsai test,Dic in Ksu. Tainan,06-2727175 */#356,06-
1234567:
/home/vbird1:/bin/bash
finger vbird1
Login: vbird1 Name: VBird Tsai test
Directory: /home/vbird1 Shell: /bin/bash
Office: Dic in Ksu. Tainan Office Phone: 06-2727175 */#356
Home Phone: 06-1234567
On since Thu Feb 26 15:21 (CST) on tty2
No mail.
Plan:
I will study Linux during this year.
chsh -l */# 用 vbird1 的身份列出系统上所有合法的shell,并且指定 csh 为自己的shell
/bin/sh
/bin/bash
/sbin/nologin */# 所谓:合法不可登入的 Shell 就是这玩意!
/bin/tcsh
/bin/csh */# 这就是 C shell 啦!
/bin/ksh
*/# 其实上面的信息就是我们在 bash 中谈到的 /etc/shells
chsh -s /bin/csh; grep vbird1 /etc/passwd
Changing shell for vbird1.
Password: */# 确认身份,请输入 vbird1 的密码
Shell changed.
vbird1:x:504:505:VBird Tsai test,Dic in Ksu. Tainan,06-2727175 */#356,06-
1234567:
/home/vbird1:/bin/csh
chsh -s /bin/bash
*/# 测试完毕后,立刻改回来!
ll $(which chsh)
-rws--x--x 1 root root 19128 May 25 2008 /usr/bin/chsh
id */# 查询某人或己的相关 UID/GID,用来判断有无某账号
id
*/# 信息其实是同一行的数据!包括会显示 UID/GID 以及支持的所有群组!
*/# 至于后面那个 context=... 则是 SELinux的内容,先不要理会他!
uid=0(root) gid=0(root)
groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),
10(wheel) context=root:system_r:unconfined_t:SystemLow-SystemHigh
新增与移除群组:groupadd, groupmod, groupdel, gpasswd 群组管理员 */# 将/etc/shadow 里头账号
失效日期 (第八字段)设定为 0 就可以让该账号无法使用
groupadd
groupadd group1 */# 群组的 GID 也是会由 500 以上最大 GID+1 来决定
grep group1 /etc/group /etc/gshadow
/etc/group:group1:x:702:
/etc/gshadow:group1:!::
groupadd -r 群组名
groupmod -g 201 -n mygroup group1 */# 将刚刚上个指令建立的group1 名称改为 mygroup , GID 为 201,不过还是不要随意的更动 GID
grep mygroup /etc/group /etc/gshadow
/etc/group:mygroup:x:201:
/etc/gshadow:mygroup:!::
groupdel */# 删除不了某个群组的原因:有某个账号 (/etc/passwd)的 initial group 使用该群组,
则修改 vbird1 的GID ,或删除 vbird1 这个使用者
groupdel mygroup
groupdel vbird1 */# 删除 vbird1 这个群组
gpasswd */# 群组管理员,然后建立起群组管理员
groupadd testgroup */# 先建立群组
gpasswd testgroup */# 给这个群组一个密码
gpasswd -A vbird1 testgroup */# 加入群组管理员为vbird1,此时 vbird1 则拥有 testgroup 的主控权,可以任意增加群组成员
grep testgroup /etc/group /etc/gshadow
id */# 发现还没有加入,于是登录vbird1用户进入
[vbird1@www ~]$ gpasswd -a vbird1 testgroup
[vbird1@www ~]$ gpasswd -a vbird3 testgroup
[vbird1@www ~]$ grep testgroup /etc/group
testgroup:x:702:vbird1,vbird
*/#
账号名称 账号全名 支援次要群组 是否可登入主机 密码
myuser1 1st user mygroup1 可以 password
myuser2 2nd user mygroup1 可以 password
myuser3 3rd user 无额外支持 不可以 password
*/# myuser3 是『不可登入系统』的账号,因此需要使用 /sbin/nologin 这个 shell 来给予
*/# 先处理账号相关属性的数据:
groupadd mygroup1
useradd -G mygroup1 -c "1st user" myuser1
useradd -G mygroup1 -c "2nd user" myuser2
useradd -c "3rd user" -s /sbin/nologin myuser3
*/# 再处理账号的密码相关属性的数据:
echo "password" | passwd --stdin myuser1
echo "password" | passwd --stdin myuser2
echo "password" | passwd --stdin myuser3
*/#
使用者 pro1, pro2, pro3 是同一个项目计划的开发人员,我想要让这三个用户在同一个目录底下工作,
但这三个用户还是拥有自己的家目录与基本的私有群组。假设我要让这个项目计划在/srv/projecta 目录下开发
groupadd projecta
useradd -G projecta -c "1st pro1" pro1;
useradd -G projecta -c "2nd pro1" pro2;
useradd -G projecta -c "3st pro1" pro3;
echo "password" | passwd --stdin pro1
echo "password" | passwd --stdin pro2
echo "password" | passwd --stdin pro3
mkdir /srv/projecta
chgrp projecta /srv/projecta
chmod 2770 /srv/projecta */# SGID 把文件的群组变成用户的有效群组
ll -d /srv/projecta
drwxrws--- 2 root projecta 4096 Feb 27 11:29 /srv/projecta */# 若没有加SGID则文档可以被删除不能被修改
owner/group/others,的三种权限:read/write/execute:
groupadd project */# 增加新的群组
useradd -G project alex */# 建立 alex 账号,且支持project
useradd -G project arod */# 建立 arod 账号,且支持project
id alex */# 查阅 alex 账号的属性
uid=501(alex) gid=502(alex) groups=502(alex),501(project) */# 确实有支持!
id arod
uid=502(arod) gid=503(arod) groups=503(arod),501(project)
mkdir /srv/ahome
ll -d /srv/ahome
drwxr-xr-x 2 root root 4096 Sep 29 22:36 /srv/ahome
chgrp project /srv/ahome
chmod 770 /srv/ahome
ll -d /srv/ahome
drwxrwx--- 2 root project 4096 Sep 29 22:36 /srv/ahome */# alex/arod 均支持 project,因此似乎没问题了
su - alex */# 先切换身份成为 alex
[alex@www ~]$ cd /srv/ahome */# 切换到群组的工作目录去
[alex@www ahome]$ touch abcd */# 建立一个空的档案
[alex@www ahome]$ exit */# 离开 alex 的身份
su - arod */# 切换身份
[arod@www ~]$ cd /srv/ahome
[arod@www ahome]$ ll abcd
-rw-rw-r-- 1 alex alex 0 Sep 29 22:46 abcd */# 群组是 alex ,对于abcd 这个档案来说则arod变成是其他人只有r的权限
[arod@www ahome]$ exit */# 此时的arod只能删掉alex建立的文档却与能更新。
chmod 2770 /srv/ahome
ll -d /srv/ahome
drwxrws--- 2 root project 4096 Sep 29 22:46 /srv/ahome
su - alex */# 切换身份
[alex@www ~]$ cd /srv/ahome
[alex@www ahome]$ touch 1234 */# alex 去建立一个档案
[alex@www ahome]$ ll 1234
-rw-rw-r-- 1 alex project 0 Sep 29 22:53 1234 */# 没错!现在 alex, arod 建立的新档案所属群组都是 project
*/# 由于两人均属于此群组,加上 umask 都是 002,这样两人才可以互相修改对方的档案!
主机的细部权限规划:ACL */# 单纯的针对某一个使用者或某一个群组,单一档案或目录进行r,w,x 的特殊权限规范
使用者 (user):可以针对使用者来设定权限
群组 (group):针对群组为对象来设定其权限
默认属性 (mask):还可以针对在该目录下在建立新档案/目录时,规范新数据的默认权限
看看如何让你的文件系统可以支持 ACL
mount */# 由挂载参数功能去查询
dumpe2fs -h /dev/hda2 |grep ‘acl‘ */# 由 superblock 内容去查询
Default mount options: user_xattr acl */# 文件系统是否支持 ACL
mount -o remount,acl / */# 默认加入了ACL ,如果没有则用此法
mount
/dev/hda2 on / type ext3 (rw,acl) */# 加入了
vi /etc/fstab */# 每次开机都生效则
LABEL=/1 / ext3 defaults,acl 1 1
ACL 的设定(user, group mask, default)
ACL 的设定技巧: setfacl, getfacl,
getfacl:取得某个档案/目录的 ACL 设定项目;
setfacl:设定某个目录/档案的 ACL 规范。『 u:[使用者账号列表]:[rwx] 』『 g:[群组列表]:[rwx] 』『 d:[ug]:使用者列表:[rwx] 』
默认umask 0022,文档建立666去掉0022则为644,目录建立777去掉0022则为755
touch bbb
ll bbb
-rw-r--r-- 1 root root 0 Feb 27 13:28 bbb
getfacl bbb
*/# file: bbb
*/# owner: root
*/# group: root
user::rw-
group::r--
other::r--
setfacl -m u:vbird1:rx bbb */# 权限部分多了个 + ,且与原本的权限 (644) 看起来差异很大!但要如何查阅呢?
ll bbb
-rw-r-xr--+ 1 root root 0 Feb 27 13:28 bbb
getfacl bbb
*/# file: bbb
*/# owner: root
*/# group: root
user::rw-
user:vbird1:r-x
group::r--
mask::r-x
other::r--
setfacl -m u::rwx bbb */# 无使用者列表,代表档案拥有者,所以上面显示 root 的权限成为 rwx了!
ll bbb
-rwxr-xr--+ 1 root root 0 Feb 27 13:28 bbb
getfacl bbb
*/# file: bbb */# 说明档名而已!
*/# owner: root */# 说明此档案的拥有者,亦即 ll 看到的第三使用者字段
*/# group: root */# 此档案的所属群组,亦即 ll 看到的第四群组字段
user::rw- */# 使用者列表栏是空的,代表档案拥有者的权限
user:vbird1:r-x */# 针对 vbird1 的权限设定为 rx ,与拥有者并不同!
group::r-- */# 针对档案群组的权限设定仅有 r
mask::r-x */# 此档案预设的有效权限 (mask)
other::r-- */# 其他人拥有的权限啰!
setfacl -m g:mygroup1:rx bbb */# 针对 mygroup1 的权限规范rx
ll bbb
-rwxr-xr--+ 1 root root 0 Feb 27 13:28 bbb
getfacl bbb
*/# file: bbb
*/# owner: root
*/# group: root
user::rwx
user:vbird1:r-x
group::r--
group:mygroup1:r-x */# 这里就是新增的部分!多了这个群组的权限设定!
mask::r-x
other::r--
mask */# 有效权限的设定
setfacl -m m:r bbb */# 使用者或群组所设定的权限必须要存在于mask的权限设定范围内才会生效
ll bbb
-rwxr--r--+ 1 root root 0 06-21 23:14 bbb
getfacl bbb
*/# file: bbb
*/# owner: root
*/# group: root
user::rwx
user:vbird1:r-x */#effective:r-- vbird1+mask 均存在者,仅有 r 而已!
group::r--
group:mygroup1:r-x */#effective:r--
mask::r--
other::r--
*/# vbird1 与 mask 的集合发现仅有 r 存在,因此 vbird1 仅具有 r 的权限而已,并不存在 x 权限
*/# 可以透过使用 mask 来规范最大允许的权限
cd /srv/projecta */# 普通账号不能进入此目录,目录具有ACL权限
-bash: cd: /srv/projecta: Permission denied */# 确实不可进入!
setfacl -m u:myuser1:rx /srv/projecta */# 设定用户能访问此目录的权限
setfacl -m u:myuser1:rx /srv/projecta
getfacl /srv/projecta
*/# file: srv/projecta
*/# owner: root
*/# group: projecta
user::rwx
user:myuser1:r-x */# 设定成功!
group::rwx
mask::rwx
other::---
cd /srv/projecta */# 使用 myuser1登录后查询能用。写入不能用。
ll -a
drwxrws---+ 2 root projecta 4096 Feb 27 11:29 . */# 确实可以查询档名
drwxr-xr-x 4 root root 4096 Feb 27 11:29 ..
touch testing
touch: cannot touch `testing‘: Permission denied */# 确实不可以写入!
touch abc1
mkdir abc2
ll -d abc* */# 使用root登录建立的目录,发现权限后面都没+,没有继承 ACL
-rw-r--r-- 1 root projecta 0 Feb 27 14:37 abc1
drwxr-sr-x 2 root projecta 4096 Feb 27 14:37 abc2
setfacl -m d:u:myuser1:rx /srv/projecta */# 让 myuser1 在/srv/projecta下一直有rx 权限
getfacl /srv/projecta
*/# file: srv/projecta
*/# owner: root
*/# group: projecta
user::rwx
user:myuser1:r-x
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:myuser1:r-x
default:group::rwx
default:mask::rwx
default:other::---
cd /srv/projecta
touch zzz1
mkdir zzz2
ll -d zzz* */# 看吧!确实有继承喔!然后我们使用 getfacl 再次确认看看!
-rw-rw----+ 1 root projecta 0 Feb 27 14:57 zzz1
drwxrws---+ 2 root projecta 4096 Feb 27 14:57 zzz2
getfacl zzz2
『 setfacl -b 档名 』即可让ACL的属性全部消失
sudo: sudo 指令, visudo (/etc/sudoers)
( 账号, 群组,限制指令, 删名, 时间间隔, 配合 su )
切换用户的原因:
Linux主机上面的一套软件,名称为 apache,额外建立一个名为 apache 的用户来启动apache 软件
telnet 程序默认是不许使用 root 的身份登入,telnet会判断登入者的 UID, 若 UID 为 0 的话,那就直接拒绝登入了
su */# su涉及 login-shell 不 non-login shell 的变量读取方法
*/# su 切换成为 root 的身份,读取的设定变量方式为 non-login shell的方式,很多原本的变量不会被改变
su
id */# 提示字符的目录是 vbird1 !
uid=0(root) gid=0(root) groups=0(root),1(bin),... */# 确实是 root 的身份!
env | grep ‘vbird1‘ */# 虽然你的 UID 已经是具有 root的身份,还是有一堆变量为原本 vbird1 的身份,
USER=vbird1
PATH=/usr/local/bin:/bin:/usr/bin:/home/vbird1/bin */# 这个影响最大!
MAIL=/var/spool/mail/vbird1 */# 收到的 mailbox 是 vbird1
PWD=/home/vbird1 */# 并非root 的家目弽
LOGNAME=vbird1
exit */# 离开 su环境!
su - */# 再次用env查看发现变成了root,此法更好
head -n 3 /etc/shadow */# vbird1 想要执行 head -n 3 /etc/shadow 一次,且已知 root 密码
head: cannot open `/etc/shadow‘ for reading: Permission denied
su - -c "head -n 3 /etc/shadow" */# 输入 root 的密码后就可以查看
root:$1$/30QpEWEBEZXRD0bh6rAABCEQD.BAH0:14126:0:99999:7:::
bin:*:14126:0:99999:7:::
daemon:*:14126:0:99999:7::: */# 注意看,身份还是 vbird1 喔!继续使用旧的身份进行系统操作!
su -l dmtsai */# 变更账号为其他用户
su -
id sshd */# 能查到的用户
su -l sshd */# 但提示无法切换
finger sshd */# 看到是Shell: /sbin/nologin
exit */# 离开shell
exit
exit */# 回到当初的环境
*/# 要想完整的切换新使用者环境『 su - username 』或『 su -l username 』会连同变量都转化到新的环境
*/# 如果想一次执行用su - -c
*/# 使用root切换成任何使用者时候不需要输入新用户的密码
无法使用『 su - sshd 』去切换系统账号 (因为系统账号的shell 是 /sbin/nologin)而sudo却可以以sshd的身份使用 sh -c 的方法来执行一连串的指令
sudo */# 要事先设定妥当,输入用户自己的密码,因此多人共管同一部主机时,sudo要比su好,至少root密码不会流出
*/# 仅有规范到/etc/sudoers 内的用户才能够执行 sudo ,得要透过 visudo 去修改这个档案
sudo -u sshd touch /tmp/mysshd */# 以 sshd 的身份在 /tmp 底下建立一个名为 mysshd 的档案
ll /tmp/mysshd
-rw-r--r-- 1 sshd sshd 0 Feb 28 17:42 /tmp/mysshd */# 这个档案的权限是由 sshd 所建立的情况
sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; echo ‘This is index.html file‘ > index.html"
*/# 以vbird1的身份建立 ~vbird/www 并于其中建立 index.html
visudo 利用群组以及免密码的功能处理 visudo,别名设定,
使用者账号 登入者的来源主机名=(可切换的身份) 可下达的指令
root ALL=(ALL) ALL */# 这是默认值
tail -n 1 /etc/shadow */# 注意!身份是 vbird1,不能查看
sudo tail -n 1 /etc/shadow */# 透过 sudo查看,输入vbird1自己的密码后vbird1 竟然可以查询 shadow
visudo */# 用root修改使任何加入 wheel 这个群组的使用者,就能够使用 sudo 切换任何身份来操作任何指令
%wheel ALL=(ALL) ALL */# 大约在 84 行左右,请将这行的 */# 拿掉 加上%后面接的意味着群组!
usermod -a -G wheel pro1 */# 将 pro1 加入 wheel 的支持
sudo tail -n 1 /etc/shadow
visudo */# 使用 root 先设定 NOPASSWD ,不需要密码即可使用 sudo
%wheel ALL=(ALL) NOPASSWD: ALL */# 大约在 87 行左右,将 */# 拿掉!
sudo tail -n 1 /etc/shadow
visudo */# 限制指令,使用者仅能使用 passwd 帮忙 root 修改其他用户的密码
myuser1 ALL=(root) /usr/bin/passwd */# 最后指令务必用绝对路径
sudo passwd myuser3
sudo passwd */# 居然能改动root的密码
visudo
myuser1 ALL=(root) !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root 必须要加以限制不能让别人有权限改了root的密码
visudo */# 别名设定
User_Alias ADMPW = pro1, pro2, pro3, myuser1, myuser2 */# 透过 User_Alias 建立出一个新账号,账号名称要使用大写字符
Cmnd_Alias ADMPWCOM = !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*,
!/usr/bin/passwd root
ADMPW ALL=(root) ADMPWCOM */# Cmnd_Alias(命令别名)、Host_Alias(来源主机名别名)
visudo */# 这四个人,只要输入『 sudo su - 』并且输入『自己的密码』后, 立刻变成 root 的身份
User_Alias ADMINS = pro1, pro2, pro3, myuser1
ADMINS ALL=(root) /bin/su
用户的特殊 shell与PAM 模块 */# 用一般账号时,理论上与会使用到 /sbin, /usr/sbin 等目录内指令所以 $PATH 变量与会含有这些目录,需要使用绝对路径
常用模块简介: securetty, nologin, pam_cracklib, login 流程
特殊的 shell :/sbin/nologin, nologin.txt
/etc/login.defs 档案中,关于密码长度应该默认是 5 个字符串长度,设定值已经被 PAM 模块所取代了
passwd 档案结构里的系统账号,使用/sbin/nologin不需要登入的合法shell,即使有密码也无法登录,但仍然可以使用资源
建立『 /etc/nologin.txt 』这个档案, 在这个档案内说明不能登入的原因,登录前显示此档案。
vi /etc/nologin.txt */# 直接编辑这个档案
This account is system account or mail account.
Please DO NOT use this account to login my Linux server.
su - myuser3 */# (此账号的shell 是 /sbin/nologin)
This account is system account or mail account.
Please DO NOT use this account to login my Linux server.
PAM 模块简介
是独立接口API ,仅是一套验证的机制也可以提供给其他程序呼叫引用并回报验证结果。
用来进行验证的数据称为模块,passwd 密码修改是由PAM 的 pam_cracklib.so 模块的功能。
藉由一个与程序相同文件名的配置文件来进行一连串的认证分析需求
/etc/securetty 会影响到 root 可登入的安全终端机, /etc/nologin 会影响到一般
使用者是否能够登入的功能之外,我们也知道 PAM 相关的配置文件在 /etc/pam.d , 说明文件在
/usr/share/doc/pam-(版本) ,模块实际在 /lib/security/ 发生任何无法登入或多重登录的错误或者是产生无法预期的错误时,
由于 PAM 模块都会将数据记载在/var/log/secure 中
PAM流程:
1. 用户开始执行 /usr/bin/passwd 这支程序,并输入密码;
2. passwd 呼叫 PAM 模块进行验证;
3. PAM 模块会到/etc/pam.d/ 找寻与程序 (passwd) 同名的配置文件;
4. 依据 /etc/pam.d/passwd 内的设定,引用相关的 PAM 模块逐步进行验证分析;
5. 将验证结果 (成功、失败以及其他讨息) 回传给 passwd 这支程序;
6. passwd 这支程序会根据 PAM 回传的结果决定下一个动作 (重新输入新密码或者通过验证!)
/etc/pam.d/passwd 配置文件
cat /etc/pam.d/passwd
*/#%PAM-1.0 */# PAM 版本的说明而已!
auth include system-auth */# 每一行都是一个验证的过程
account include system-auth */# include请呼后面的档案作为这个类别的验证
password include system-auth */#每一行都要重复呼 /etc/pam.d/system-auth 那个档案进行验证
*/# 验证类别 控制标准 PAM 模块与该模块的参数
pam_nologin 说明文件档在: /usr/share/doc/pam-0.99.6.2/txts/README.pam_nologin
/etc/pam.d/*:每个程序个别的 PAM 配置文件;
/lib/security/*:PAM 模块档案的实际放置目录;
/etc/security/*:其他 PAM 环境的配置文件;
/usr/share/doc/pam-*/:详细的 PAM 说明文件
PAM 模块设定法:验证类别(type)、控制标准(flag)、模块与参数
type 类别:
auth (认证)account(授权),session(会话) password(密码), */#在 /var/log/secure 里很多关于pam的说明,『session open, session close』的信息!
control flag 控制标志:
required(必须继续不论失败成功),requisite(失败就终止),sufficient(成功立刻结束),optional(显示信息)
cat /etc/pam.d/login login 也呼叫多次 system-auth
cat /etc/pam.d/system-auth
pam_securetty.so 登录root限制,
pam_nologin.so 限制一般用户
pam_selinux.so 细部管理权限的功能
pam_console.so 如 RS232 等特殊的终端接口登入系统
pam_loginuid.so 对UID进行规范
pam_env.so 设定环境变量 额外环境变量参考/etc/security/pam_env.conf
pam_unix.so 验证阶段的认证功能 授权阶段的账号许可证管理 会议阶段的登录文件记录 密码更新阶段的检验
pam_cracklib.so:检验密码的强度
pam_limits.so 提供ulimit
login 的 PAM 验证机制流程:
验证阶段:会先经过 pam_securetty.so 判断,如果使用者是 root 时,则会参考 /etc/securetty 的设定;
接下来(b)经过 pam_env.so设定额外的环境变量;再(c)透过pam_unix.so 检验密码,
若通过则回报 login 程序;若不通过则(d)继续往下以pam_succeed_if.so 判断 UID 是否大于 500 ,
若小于 500 则回报失败,否则再往下 (e)以pam_deny.so 拒绝联机。
认证阶段 (auth):首先,(a)会先经过 pam_securetty.so 判断,如果使用者是 root 时,则会参
考 /etc/securetty 的设定; 接下来(b)经过 pam_env.so 设定额外的环境变量;再(c)透过
pam_unix.so 检验密码,若通过则回报 login 程序;若不通过则(d)继续往下以
pam_succeed_if.so 判断 UID 是否大于 500 ,若小于 500 则回报失败,否则再往下 (e)以
pam_deny.so 拒绝联机。
授权阶段 (account):(a)先以 pam_nologin.so 判断 /etc/nologin 是否存在,若存在则不让一
般使用者登入; (b)接下来以 pam_unix 进行账号管理,再以 (c) pam_succeed_if.so 判断 UID
是否小于 500 ,若小于 500 则先记录登录信息。(d)最后以 pam_permit.so 允许该账号登入。
密码阶段 (password):(a)先以 pam_cracklib.so 设定密码仅能尝试错误 3 次;(b)接下来以
pam_unix.so 透过 md5, shadow 等功能进行密码检验,若通过则回报 login 程序,若不通过则
(c)以 pam_deny.so 拒绝登入。
会话阶段 (session):(a)先以 pam_selinux.so 暂时关闭 SELinux;(b)使用 pam_limits.so 设定
好用户能够操作的系统资源; (c)登入成功后开始记录相关信息在登录文件中; (d)以
pam_loginuid.so 规范不同的 UID 权限;(e)开始 pam_selinux.so 的功能
为什么 root 无法以 telnet 直接登入系统,但是即能够使用 ssh 直接登入?
一般来说, telnet 会引用 login 的 PAM 模块,而 login 的验证阶段会有 /etc/securetty
的限制! 由于进程联机属于 pts/n (n 为数字) 的动态终端机接口装置名称,并没有写入到
/etc/securetty , 因此 root 无法以 telnet 登入进程主机。至于ssh 使用的是
/etc/pam.d/sshd 这个模块, 你可以查阅一下该模块,由于该模块的验证阶段幵没有加入
pam_securetty ,因此就没有 /etc/securetty 的限制!故可以从进程直接联机到服务器端
其他相关档案: limits.conf,
ulimit 功能中, 除了修改使用者的 ~/.bashrc 配置文件之外,其实系统管理员
可以统一藉由 PAM 来管理的! 那就是 /etc/security/limits.conf 这个档案的设定了
vi /etc/security/limits.conf */# vbird1 这个用户只能建立 100MB 的档案,大于 90MB 会警告
vbird1 soft fsize 90000
vbird1 hard fsize 100000
*/#账号 限制依据 限制项目 限制值
ulimit -a
file size (blocks, -f) 90000
dd if=/dev/zero of=test bs=1M count=110
File size limit exceeded
ll -k test
-rw-rw-r-- 1 vbird1 vbird1 90000 Mar 4 11:30 test */# 果然有限制到了
dd if=/dev/zero of=test bs=1M count=110
File size limit exceeded
ll -k test
-rw-rw-r-- 1 vbird1 vbird1 90000 Mar 4 11:30 test */# 果然有限制到了
vi /etc/security/limits.conf */# 限制 pro1 这个群组,每次仅能有一个用户登入系统 (maxlogins)
@pro1 hard maxlogins 1
*/# 如果要使用群组功能的话,这个功能似乎对初始群组才有效喔!
*/# 而如果你尝试多个 pro1 的登入时,第二个以后就无法登入了。
*/# 而且在 /var/log/secure 档案中还会出现如下的信息:
*/# pam_limits(login:session): Too many logins (max 1) for pro1
Linux 主机上的用户讯息传递
查询使用者: w, who, last, lastlog
last : */# 当月登录者信息(Red Hat)所有登陆者信息(CentOS 5.x 版以后)
w : */# 目前已登入在系统上面的用户
w */# 第一行显示目前的时间、开机 (up) 多久,几个用户在系统上平均负载等
13:13:56 up 13:00, 1 user, load average: 0.08, 0.02, 0.01
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT */# 第二行只是各个项目的说明
root pts/1 192.168.1.100 11:04 0.00s 0.36s 0.00s -bash */# 第三行以后,每行代表一个使用者。如上所示,root 登入并取得终端机名pts/1之意
vbird1 pts/2 192.168.1.100 13:15 0.00s 0.06s 0.02s w
who
root pts/1 2009-03-04 11:04 (192.168.1.100)
vbird1 pts/2 2009-03-04 13:15 (192.168.1.100)
lastlog */# lastlog 会去读取 /var/log/lastlog 档案
*/# 每个账号的最近登入的时间
使用者对谈: write, mesg, wall
who */# 有谁在线
root pts/1 2009-03-04 11:04 (192.168.1.100)
vbird1 pts/2 2009-03-04 13:15 (192.168.1.100) */# 有看到 vbird1 在线
write vbird1 pts/2
Hello, there:
Please don‘t do anything wrong... */# 这两行是 root 写的信息!
write root */# 一般用户写给root,root可以也不接受用mesg n
mesg n */# 不想接受任何信息可以下达的命令,除了root以外。
mesg y */# 解开命令
wall "I will shutdown my linux server..." */# 对所有系统上面的用户传送简讯
使用者邮件信箱: mail */# 利用mailbox收发信件,都会放置在 /var/spool/mail 里面
mail vbird1 -s "nice to meet you"
Hello, D.M. Tsai
Nice to meet you in the network.
You are so nice. byebye!
. */# 结束时,最后一行输入小数点 .即可!
Cc: */# 这里是所谓的『副本』,不需要寄给其他人,所以直接 [Enter]
*/# 出现提示字符,表示输入完毕了
mail -s */# 先用vi 将信件内容编好,再使用数据流重导向取代键盘输入
mail -s "bashrc file content" vbird < ~/.bashrc */# 家目录下的环境变量文件 (~/.bashrc)寄给自己
*/# N 代表该封信件尚未读过 mail 内部的指令有哪些在 &之后输入 ?
&?看提示符
手动建立账号(特殊账号):
useradd 可以帮我们自动设定好UID/GID 家目录以及家目录相关的权限设定
手动建立账号要涉及GID/UID 等权限,检查群组、账号相关的指令密码转换的 pwconv 及 pwuconv。
一些检查工具:pwck, pwconv, pwunconv, chpasswd
pwck
检查 /etc/passwd 这个账号配置文件内的信息与实际的家目录是否存在
如果 /etc/passwd 内的数据字段错误时,会提示使用者修订。
grpck 相对应的群组检查
pwconv 将 /etc/passwd 内的账号于密码,移动到 /etc/shadow 当中,可以比对两个档案,/etc/passwd 对应/etc/shadow里没有密码时
会去 /etc/login.defs 取用相关的密码数据,将原本的/etc/passwd 内相对应的密码栏变成 x
pwunconv 将 /etc/shadow 内的密码栏数据写回 /etc/passwd 当中,并且删除 /etc/shadow 档案。
chpasswd DES 加密方法,读入未加密前的密码,经过加密后, 将加密后的密码写入/etc/shadow 中,
由 Standard input 读入数据,每笔数据的格式是『 username:password 』
echo "dmtsai:abcdefg" | chpasswd -m */# 用户账号为dmtsai ,想要更新他的密码 (update) , 假如他的密码是 abcdefg 的话
passwd --stdin 代替了以上命令,除了root以为的系统管理员的账号尽量避免使用数字型态的账号,修改用户相关的信息
账号与群组是与 /etc/group, /etc/shadow, /etc/passwd, /etc/gshadow 有关,因此,整个动作是:
1. 先建立所需要的群组 ( vi /etc/group );
2. 将 /etc/group 与 /etc/gshadow 同步化 ( grpconv );
3. 建立账号的各个属性 ( vi /etc/passwd );
4. 将 /etc/passwd 与 /etc/shadow 同步化 ( pwconv );
5. 建立该账号的密码 ( passwd accountname );
6. 建立用户家目录 ( cp -a /etc/skel /home/accountname );
7. 更改用户家目录的属性 ( chown -R accountname.group /home/accountname )。
vi /etc/group */# 建立群组 normalgroup ,假设 520 这个 GID 没有被使用!并且同步化gshadow
normalgroup:x:520: */# 在最后一行加入 !
grpconv
grep ‘normalgroup‘ /etc/group /etc/gshadow */# 同步化
/etc/group:normalgroup:x:520:
/etc/gshadow:normalgroup:x:: */# 最后确定 /etc/group, /etc/gshadow 都存在这个群组才行!搞定群组啰!
vi /etc/passwd */# 建立 normaluser 这个账号,假设 UID 700 没被使用掉!
normaluser:x:700:520::/home/normaluser:/bin/bash */# 在最后一行加入 !
pwconv */# 同步化密码,并且建立该用户的密码
grep ‘normaluser‘ /etc/passwd /etc/shadow
/etc/passwd:normaluser:x:700:520::/home/normaluser:/bin/bash
/etc/shadow:normaluser:x:14307:0:99999:7:::
passwd normaluser */# 确定 /etc/passwd, /etc/shadow 都有 normaluser 的信息了!但是密码还不对
Changing password for user normaluser.
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully.
cp -a /etc/skel /home/normaluser */# 建立用户家目录,并且修订权限!
chown -R normaluser:normalgroup /home/normaluser
chmod 700 /home/normaluser
大量建置账号模板(适用 passwd --stdin 选项)
大量建置账号的范例(适用于连续数字,如学号)
*/# script在 zh_TW.big5 下建立如需转成万国码 (utf8)格式用iconv处理语系问题
vi account1.sh
*/#!/bin/bash
*/# 这支程序用来建立新增账号,功能有:
*/# 1. 检查 account1.txt 是否存在,并将该档案内的账号取出;
*/# 2. 建立上述档案的账号;
*/# 3. 将上述账号的密码修订成为『强制第一次进入需要修改密码』的格式。
*/# 2009/03/04 VBird
export PATH=/bin:/sbin:/usr/bin:/usr/sbin */# 检查 account1.txt 是否存在
if [ ! -f account1.txt ]; then
echo "所需要的账号档案不存在,请建立 account1.txt ,每行一个账号名称"
exit 1
fi
usernames=$(cat account1.txt)
for username in $usernames
do
useradd $username */# 新增账号
echo $username | passwd --stdin $username */# 与账号相同的密码
chage -d 0 $username */# 强制登入修改密码
done
vi account1.txt
std01
std02
std03
std04
std05
std06
std07
std08
std09
std10
vi addStu.sh
*/#!/bin/bash
export LANG=zh_TW.big5
export PATH=/sbin:/usr/sbin:/bin:/usr/bin
accountfile="user.passwd" */# 1. 进行账号相关的输入先!
echo ""
echo "例如学号为: 4960c001 到 4960c060 :"
echo "账号开头代码为 :4"
echo "账号层级或年级为 :960c"
echo "号码数字位数为(001~060):3"
echo "账号开始号码为 :1"
echo "账号数量为 :60"
echo ""
read -p "账号开头代码 ( Input title name, ex> std )======> " username_start
read -p "账号层级或年级 ( Input degree, ex> 1 or enter )=> " username_degree
read -p "号码部分的数字位数 ( Input \ */# of digital )======> " nu_nu
read -p "起始号码 ( Input start number, ex> 520 )========> " nu_start
read -p "账号数量 ( Input amount of users, ex> 100 )=====> " nu_amount
read -p "密码标准 1) 与账号相同 2)随机数自定丿 ==============> " pwm
if [ "$username_start" == "" ]; then
echo "没有输入开头的代码,不给你执行哩!" ; exit 1
fi
testing0=$(echo $nu_nu | grep ‘[^0-9]‘ ) */# 判断数字系统
testing1=$(echo $nu_amount | grep ‘[^0-9]‘ )
testing2=$(echo $nu_start | grep ‘[^0-9]‘ )
if [ "$testing0" != "" -o "$testing1" != "" -o "$testing2" != "" ]; then
echo "输入的号码不对啦!有非为数字的内容!" ; exit 1
fi
if [ "$pwm" != "1" ]; then
pwm="2"
fi */# 2. 开始输出账号与密码档案!
[ -f "$accountfile" ] && mv $accountfile "$accountfile"$(date +%Y%m%d)
nu_end=$(($nu_start+$nu_amount-1))
for (( i=$nu_start; i<=$nu_end; i++ ))
do
nu_len=${ */#i}
if [ $nu_nu -lt $nu_len ]; then
echo "数值的位数($i->$nu_len)已经比你设定的位数($nu_nu)还大!"
echo "程序无法继续"
exit 1
fi
nu_diff=$(( $nu_nu - $nu_len ))
if [ "$nu_diff" != "0" ]; then
nu_nn=0000000000
nu_nn=${nu_nn:1:$nu_diff}
fi
account=${username_start}${username_degree}${nu_nn}${i}
if [ "$pwm" == "1" ]; then
password="$account"
else
password=$(openssl rand -base64 6)
fi
echo "$account":"$password" | tee -a "$accountfile"
done */# 3. 开始建立账号与密码!
cat "$accountfile" | cut -d‘:‘ -f1 | xargs -n 1 useradd -m
chpasswd < "$accountfile"
pwconv
echo "OK!建立完成!
*/# 如果有需要建立同一班级具有同一群组的话,可以先使用 groupadd 建立群组后, 将该群组加入
『 cat "$accountfile" | cut -d‘:‘ -f1 | xargs -n 1 useradd -m -g groupname 』那行
vi delaccount2.sh
*/#!/bin/bash
usernames=$(cat user.passwd | cut -d ‘:‘ -f 1)
for username in $usernames
do
echo "userdel -r $username"
userdel -r $username
done
sh delaccount2.sh
想将本服务器的账号分开管理,分为单纯邮件使用,与可登入系统账号两种。
其中若为纯邮件账号时,将该账号加入 mail 为初始群组,
且此账号不可使用 bash 等 shell 登入系统。若为可登入账号时,
将该账号加入 youcan 这个次要群组
grep mail /etc/group
grep youcan /etc/group
groupadd youcan */# 观察群组不存在时建立群组。
vim popuser.sh
*/#!/bin/bash */# 账号名称为 pop1, pop2, pop3
for username in pop1 pop2 pop3
do
useradd -g mail -s /sbin/nologin -M $username
echo $username | passwd --stdin $username
done
sh popuser.sh
让 test 这个账号具有 root 的权限,因为root 的 UID 与 GID 均为 0 ,所以要让
test 变成 root 的权限,那就将 /etc/passwd 里面test的 UID 与 GID 字段变成 0 即可。
这个账号是暂时失效: 将 /etc/passwd 的 shell 字段写成 /sbin/nologin ,即可让该账号暂时无法登入主机;
将 /etc/shadow 内的密码字段,增加一个 * 号在最前面,这样该账号亦无法登入!
将 /etc/shadow 第八个字段,账号取消日期设定成小于目前日期的数字,那他就无法登入系统了
在使用 useradd 的时候,新增的账号里面的 UID, GID 还有其他相关的密码控制,
都是在 /etc/login.defs 还有 /etc/default/useradd 里面规定好的。
由于使用 useradd 的时候,会自动以 /etc/skel 做为默认得家目录。
建立一个使用者名称 alex, 他所属群组为 alexgroup, 预计使用 csh, 他的全名为 "Alex Tsai",
且他还得要加入 users 群组:groupadd alexgroup
useradd -c "Alex Tsai" -g alexgroup -G users -m alex
编辑 /etc/default/useradd ,将里头的 HOME=/home 改成 HOME=/account
将用户家目录被放置到 /account 这个目录下,
让 dmtsai 这个使用者,加入 vbird1, vbird2, vbird3 这三个群组
usermod -a -G vbird1,vbird2,vbird3 dmtsai ,且不影响 dmtsai 原本已经支持的次要群组
------磁盘配额(Quota)与进阶文件系统管理-----------
磁盘阵列 (RAID) 及逻辑滚动条文件系统 (LVM),管理与维护用户可用的磁盘容量
Quota 管理文件系统的
限制某一群组所能使用的最大磁盘配额 (使用群组限制):
限制某一用户的最大磁盘配额 (使用用户限制):
以 Link 的方式,来使邮件可以作为限制的配额 (更改 /var/spool/mail 这个路径):
限制 inode 用量:可以管理使用者可以建立的『档案数量』;
限制 block 用量:管理用户磁盘容量的限制,较常见为这种方式。
root 就不能设定quota 只对一般身份使用者有效,不能针对某个目录来进行 Quota 的设计,
但你可以针对某个文件系统(filesystem) 来设定。文件系统主要规划为存放属性的 inode 与实际档案数据的
block ,Quota 既然是管理文件系统,所以也可以管理 inode 和 block
不管是 inode/block ,限制值都有两个,分别是 soft 与 hard ,soft是柔性劝导,hard是硬性规定。
在soft ,而低于hard时,会予以警告并会产生grace倒数。达到 hard 限值时,用户的磁盘使用权可能会被锁住。
制作账号环境,有五个账号
vi addaccount.sh
*/#!/bin/bash
*/# 使用 script 来建立实验 quota 所需的环境
groupadd myquotagrp
for username in myquota1 myquota2 myquota3 myquota4 myquota5
do
useradd -g myquotagrp $username
echo "password" | passwd --stdin $username
done
sh addaccount.sh
df -h /home */# 由于 Quota 必项要核心与文件系统支持,先查一下, /home 是否是个独立的 filesystem
Filesystem Size Used Avail Use% Mounted on
/dev/hda3 4.8G 740M 3.8G 17% /home */# 鸟哥主机的 /home 确实独立的!
mount | grep home
/dev/hda3 on /home type ext3 (rw)
mount -o remount,usrquota,grpquota /home */# 手动加入quota支持,Linux 传统的 ext2/ext3 肯定支持 Quota VFAT 文件系统并不支持
mount | grep home
/dev/hda3 on /home type ext3 (rw,usrquota,grpquota)
重新挂载时,系统会同步更新 /etc/mtab 这个档案。
要确定 /etc/mtab 已经加入 usrquota, grpquota 的支持到你所想要设定的文件系统中。
使用者与群组的 quota 文件系统支持参数分别是:usrquota, grpquota
vi /etc/fstab */# 修改 /etc/fstab
LABEL=/home /home ext3 defaults,usrquota,grpquota 1 2 */# 于 default后面加上两个参数!
umount /home
mount -a
mount | grep home
/dev/hda3 on /home type ext3 (rw,usrquota,grpquota)
建立quota记录文件,透过分析整个文件系统中,每个使用者(群组)拥有的档案总量,将数据记录在该文件系统给的最顶层目录。
然后在该记录文件中再使用每个账号(或群组)去规范磁盘使用量。
quotacheck :扫瞄文件系统并建立 Quota 的记录文件
ll -d /home/a* */# 变动会记录在以下两个档案中。要建立 aquota.user,aquota.group,记得使用的是 quotacheck
-rw------- 1 root root 8192 Mar 6 11:58 /home/aquota.group
-rw------- 1 root root 9216 Mar 6 11:58 /home/aquota.user
quotacheck -avug */# /home 独立的文件系统,因此搜寻结果会将两个记录文件放在 /home 底下,为重要信息。
quotacheck -avug -mf */# 需要强制扫瞄已挂载的文件系统时,启动 quota 功能再进行 quotacheck
Quota 启动、 关闭与限制值设定
quotaon -auvg */# 启动 user/group 的 quota
/dev/hda3 [/home]: group quotas turned on
/dev/hda3 [/home]: user quotas turned on
quotaon -uv /var */# 特殊用法,假如你的启动 /var 的 quota 支持,那么仅启动 user quota 时
*/# 针对整个系统有 usrquota, grpquota 参数的文件系统 quotacheck 扫瞄
Quota 可公平的分配系统上面的磁盘容量给用户;分配的资源可以是磁盘容量(block)或可建立档案数量(inode);
Quota 的限制可以有 soft/hard/grace time 等重要项目;
Quota 仅能针对整个 filesystem 进行限制,不是针对目录喔!
Quota 的使用必项要核心与文件系统均支持。文件系统的参数必项有 usrquota, grpquota
Quota 实作的指令有 quotacheck, quotaon, edquota, repquota 等;
磁盘阵列 (RAID) 有硬件与软件之分,Linux 操作系统可支持软件磁盘阵列,透过 mdadm 套件达成;
磁盘阵列建置的考虑依据为『容量』、『效能』、『资料可靠性』等;
磁盘阵列所建置的等级常见有的 raid0, raid1, raid0+1, raid5 及 raid6
硬件磁盘阵列的装置文件名与 SCSI 相同,至于 software RAID 则为 /dev/md[0-9]
软件磁盘阵列的状态可藉由 /proc/mdstat 档案来了解;
LVM 强调的是『弹性的变化文件系统的容量』;
与 LVM 有关的组件有: PV/VG/PE/LV 等组件,可以被格式化者为 LV
LVM 拥有快照功能,快照可以记录 LV 的数据内容,并与原有的 LV 共享未更动的数据,备份与还原就变的很简单;
Ext3 透过 resize2fs 指令,可以弹性的调整文件系统的大小
系统可以透过 at 这个指令来排程单一工作的任务!『at TIME』为指令下达的方法,当 at 进入
排程后, 系统执行该排程工作时,会到下达时的目录进行任务;
at 的执行必须要有 atd 的支持,且 /etc/at.deny 为控制是否能够执行的使用者账号;
透过 atq, atrm 可以查询与删除 at 的工作排程;
batch与 at 相同,不过 batch 可在 CPU 工作负载小于 0.8 时才进行后续的工作排程;
系统循环例行性工作排程使用 cron 这个服务,同时利用 crontab -e 及 /etc/crontab 进行排程的安排;
crontab -e 设定项目分为六栏,『分、时、日、月、周、指令』为其设定依据;
/etc/crontab 设定分为七栏,『分、时、日、月、周、执行者、指令』为其设定依据;
anacron 配合/etc/anacrontab 的设定,可以唤醒停机期间系统未进行的 crontab 任务