- 版权说明:重拾Linux笔记,禁止转载哈。
- 关于勘误:如有错误,请直接回复批评与指教。笔者会及时更新滴。
- 关于重拾:笔者自我感觉对LinuxOS理解不够深入,尴尬ing。想从以下两方面入手给自己一些启发:
- Linux应用面(完结)
- Linux内核面(整理中)
- 重拾目的:笔者从事工作侧重于大吞吐量高性能分布式系统,对服务端优化部分理解不够深入,虽然现在找到一些突破方向,但是希望自己能够在OS层面找到一些突破口。目前纯YY
Linux应用面
权限命令:
- chown :改变文件拥有者。/etc/passwd 必须存在
- chgrp :改变文件所属群组。/etc/group必须存在
- chmod :改变文件的权限, SUID, SGID, SBIT等等的特性
- chmod 644 .bashrc
- chmod u=rwx,go=rx .bashrc
目录:
- 目录的权限r,x通常配合在一起使用,但w权限需要慎重。
文件格式:
- 指令属于二进制文件(binary)
- 可读取的纯文本档(ASCII)
- last 读取 数据格式文件(data)
- -文件,d目录,l连结档,b硬盘软盘等存储接口设备(dev/sda),c键盘鼠标一次性读取的接口设备。
- s数据接口文件支持socket通信(var/run),p(FIFO.pipe)特殊的文件类型主要解决多程序同时存取一个文件所造成的错误问题。
查询系统版本:
- uname -r查询linux核心版本号
- lsb_release -a 查询LSB版本,以及distribution
目录操作:
- . 代表此层目录
- .. 代表上一层目录
- - 代表前一个工作目录
- ~ 代表『目前使用者身份』所在的家目录
- ~account 代表 account 这个使用者的家目录(account是个帐号名称)
- cd:变换目录
- pwd:显示目前的目录 pwd -P显示真实的物理目录
- mkdir:创建一个新的目录 -p递归父目录, -m 增加权限
- rmdir:删除一个空的目录 -p递归父目录, -r 递归删除
打印出系统变量:
文件与目录管理
- ls -al -full-time ~
cp -i 存在是否覆盖 -a附带所有属性,即复制之后权限不变 -r递归 -l实体连结 -s符号链结[捷径,快捷方式,-d复制捷径] -u 复制差异文件
是否需要完整的保留来源文件的资讯?
- 来源文件是否为连结档 (symbolic link file)?
- 来源档是否为特殊的文件,例如 FIFO, socket 等?
- 来源档是否为目录?
rm -f忽略文件不存在的警告 -i互动问答 -r递归
mv -f强势覆盖 -i互动询问 -u 目标文件存在且source比较新才会升级
获取文件名或目录名
- basename 获取文件名 dirname获取目录名 用户home目录为.
文件内存查阅
- cat -n加印行号[-b排除空行号] -A完整显示(包含特殊字符)
- tac 相反输出
- nl(添加行号列印) -b指定行号指定的方式(a空白行显示 t忽略空白行显示) -n指定行号表现的方式(ln行号左边显示,rn行号右边显示且不加0,rz在右边显示且加0)-w行号栏位占用的位数
- more(一页一页的翻动)
- 空白键 (space):代表向下翻一页;
- Enter :代表向下翻『一行』;
- /字串 :代表在这个显示的内容当中,向下搜寻『字串』这个关键字;
- :f :立刻显示出档名以及目前显示的行数;
- q :代表立刻离开 more ,不再显示该文件内容。
- b 或 [ctrl]-b :代表往回翻页,不过这动作只对文件有用,对管线无用
- less
- 空白键 :向下翻动一页;
- [pagedown]:向下翻动一页;
- [pageup] :向上翻动一页;
- /字串 :向下搜寻『字串』的功能;
- ?字串 :向上搜寻『字串』的功能;
- n :重复前一个搜寻 (与 / 或 ? 有关!)
- N :反向的重复前一个搜寻 (与 / 或 ? 有关!)
- q :离开 less 这个程序;
- head(取出前几行) -n (可以跟上负数)
- tail(取出末尾几行) -n -f持续侦测内容(ctr+c跳出)
- od(非纯文档展示) -t(a默认的字节,c使用ASCII,dfox[size]不同进制输出)
修改文件时间或建置新档
ls -l -time=[atime,ctime,mtime]
- mtime默认的,文件内容变更的时间
- atime文件被查看访问的时间
- ctime文件权限属性变更的时间
- 全部cp是不会绝对完整的复制,ctime排除。
范例三:修改案例二的 bashrc 文件,将日期调整为两天前
[root@www tmp]# touch -d "2 days ago" bashrc
# 不过, ctime 并没有跟著改变喔!
范例四:将上个范例的 bashrc 日期改为 2007/09/15 2:02
[root@www tmp]# touch -t 0709150202 **重点内容**bashrc
[root@www tmp]# ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc
# atime 与 mtime 都改变了,但是 ctime 则是记录目前的时间!-t参数影响ctime。而-d不影响
文件、目录的默认权限和隐藏权限
- umask 002 减去-———w-权限 = -rw-rw-r–
- 文件的默认权限:666 目录的默认权限是777
文件隐藏属性
- lsattr -a将隐藏档的属性也秀出来 -d如果是目录,仅列出目录本身的属性 -R连同子 目录的数据也一并列出来
- chattr [+-=] i让文件无法被更动,系统安全性 a文件只能添加数据,而不能删除修改
文件特殊权限s,t
检测文件类型
- file
- -命令档名的搜寻
- which(寻找[运行档])
- 文件档名的搜寻
- whereis,locate搜索系统文件DB
- updatedb手动升级DB
- updatedb:根据 /etc/updatedb.conf 的配置去搜寻系统硬盘内的档名,并升级 /var/lib/mlocate 内的数据库文件;
- locate:依据 /var/lib/mlocate 内的数据库记载,找出使用者输入的关键字档名。
- find扫硬盘
- find -mtime[+,-] n n天之前之内之间变更的文件
-newer 比该文件还有新的文件档名
-uid -gid -user -group -nouser -nogroup
-name
- find ./ser* -exec ls -l {} \;
-exec 之后增加对find结果集进行操作的命令,{}代表find结果集 \;代表结束命令,反斜杠转义
vim命令
- :wq! 强制退出并写入。!有强制的意思
- :w [filename] 另存
- :r [filename] 光标处读入整个文件
:! command 暂时离开vi到指令模式下执行command :! ls /home
一般模式指令:
行操作:删除dd , 复制yy ,粘贴pp
字符操作:x删除
搜素:/
kill -9 %1 杀死vim进程
区域选择(Visual Block)
- [ctrl]+v 进入区域选择
- 移动光标后,y复制到寄存器。
- 移动复制目的光标处,p粘贴
多档案编辑
- vim test1.sh test2.sh
- :files
- :n下一个档案
- :N上一个档案
多窗口
- vim test2.sh
- :sp test.sh
- [ctrl]+w j|k 切换框 重复点击
预设vim环境
vim ~/.vimrc
DOS与Linux文件转换
- DOS断行字符^M$
- Linux断行字符$
- dos2unix [-kn] file [newfile]
- unix2dos -k man.config
中文编码的问题
- linux默认语系 /etc/sysconfig/i18n
- 终端界面bash语系 LANG 。在i18n文件配置
- 档案原来的编码
- 终端软件->设置显示字符编码
语系编码转换
iconv —list
iconv -f big5 -t utf8 vi.big5 -o vi.utf8
正体中文转换简体中文。(需要utf8先转换成本地语系,在从本地语系做出转换)
[root@www vitest]# iconv -f utf8 -t big5 vi.utf8 | \
> iconv -f big5 -t gb2312 | iconv -f gb2312 -t utf8 -o vi.gb.utf8
alias 别名
alias ll=‘ls -al’
unalias 别名 取消别名
Bash脚本开发
- tab 第一个字符后面,连续两次,搜索命令。补全命令
- tab 第二个字符后面,补全文件
- 变量配置守则
name=chaoli.lcl echo $name [${name}]
- 变量与变量内容以等号连接
- 等号两边不能直接接空格符
- 变量名称只能是英文字母与数字,但开头不能是数字
- 变量内容若有空格可以使用双引号或者单引号结合起来。
双引号:保持原本特性。内容可继续读变量
单引号:一般的纯文本字符
- \逃脱字符,可以将特殊符号变成一般字符
- 在一串命令中,还需要其他命令提供信息,可以使用反单引号[
命令
],[$(命令)]
version=${uname -r} echo $version
ps:反单引号[
],代表先运行返单引号的命令。运行的结果先输出
- 变量为扩增变量内容时,可用” 变量内容”或者 {变量}累加
path=“$PATH”:/home/bin
- 若该变量需要在其他子程序运行,则需要export来使变量变成环境变量
export PATH
- 系统变量大写,自行配置变量小写
- 取消变量的方法unset eg:unset myname
查看更多的环境的变量 env 与 export ,set
特殊变量
$即$$
为目前shell的PID
?即$?为上一次命令的回传值
locale 影响显示结果的语系变量 语系文件地址/usr/lib/locale
read读取键盘
read -p “提示性文字” -t 30 var
declare/typeset
declare -a数组类型 -i整数 -x转换成环境变量 -r只读属性
+取消
declare -p sum
可以列出变量的类型
数组变量:${var[1]}
- 与文件系统及程序的限制关系: ulimit -a显示所有限制额度
变量内容的删除,取代与替换
${var#key}
从头开始的数据符合key的最短数据删除
${var##key}
从头开始的数据符合key的最长数据删除
${var%key}
从尾向前符合key的最短数据删除
${var%%key}
从尾向前符合key的最长数据删除
${var/oldStr/newStr
}变量符合第一个旧字符的将会被新字符代替
${var//oldStr/newStr}
变量符合旧字符的全部字符将会被新字符代替
变量的测试与内容替换
- 测试变量是否配置
username= username−root如果username为未配置的(不包括空字符),则不进行替换。username= {username:-root} 如果username配置为空字符串,或者未配置,则进行替换
- 替换旧变量
unset str;var=${str=newvar} str没有变量内容,则进行替换
- 测试是否有此变量
unset str;var=${str?无此变量} 如果str为null,则输出“无此变量”
历史命令history
history [n]最近的第n个命令
history [-c]清除目前shell中所有的命令
history [-raw] r读取到内存 w写入到文件 a新增的命令增加到文件中
路径与命令搜索顺序
- 相对/绝对路径运行命令
- alias运行命令
- bash内建的命令来运行
- $PATH这个变量的顺序搜索到第一个命令来运行
Bash的进站与欢迎信息
/etc/issue 系统登录
/etc/issue.net 远程登陆
/etc/motd 欢迎信息,向所有的登陆者显示。
Bash的环境配置文件
login与non-login shell读取的配置文件不同
1. login读取
1.1. 系统配置 /etc/profile
1.2.个人配置~/.bash_profile或~/.bash_login或~/.profile
1.3. ./etc/skel/.bashrc复制到家目录。可恢复.bashrc的缺失
读取生效配置
source ~./bashrc
.~/.bashrc
其他配置文件
1./etc/man.config man命令搜索的path配置
~/.bash_history
~/.bash_logout
终端机的环境配置,stty与set
1.stty -a显示按键内容
eg: etase^h
2.echo $- 显示所有的set信息
3./etc/inputrc
组合按键 运行结果
Ctrl + C 终止目前的命令
Ctrl + D 输入结束 (EOF),例如邮件结束的时候;
Ctrl + M 就是 Enter 啦!
Ctrl + S 暂停屏幕的输出
Ctrl + Q 恢复屏幕的输出
Ctrl + U 在提示字符下,将整列命令删除
Ctrl + Z 『暂停』目前的命令
通配符与特殊符号
数据重定向
- > >>输出
- < <<输入(<<“str”结束输入)
- 2>>错误输出
/dev/null 垃圾桶黑洞装置与特殊写法filename 2>&1,&> filename
[dmtsai@www ~]$ find /home -name .bashrc 2> /dev/null
/home/dmtsai/.bashrc <==只有 stdout 会显示到屏幕上, stderr 被丢弃了
[dmtsai@www ~]$ find /home -name .bashrc > list 2> list <==错误
[dmtsai@www ~]$ find /home -name .bashrc > list 2>&1 <==正确
[dmtsai@www ~]$ find /home -name .bashrc &> list <==正确
命令运行的判断依据: ;,&&,||
- cmd1 && cmd2 || cmd3
- 范例三:我不清楚 /tmp/abc 是否存在,但就是要创建 /tmp/abc/hehe 文件
[root@www ~]# ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe
- 截取命令:cut,grep
- cut
-d:后面接上分割符,与-f一起使用
-f:依据-d分割的数据段.-f取出第几段
-c:取出固定的字符区间
last | cut -d ’ ’ -f 1
export | cut -c 12-
- grep
-a:将binary文件以text文件的方式搜寻数据
-c:计算找到’搜寻字符串’的次数
-i:忽略大小写的不同,所以大小写视为相同
-n:输出行号
-v:反选
—color=auto:显示关键词颜色
last | grep ‘root’ |cut -d ’ ’ -f1
- 排序命令:sort,wc,uniq
- sort
-f:忽略大小写的差异
-b:忽略前面的空格符
-M:以月份名来排序
-n:使用纯数字排序
-r:反向排序
-u:就是uniq,相同数据,仅出现一行代表
-t:分隔符,默认是[tab]分割
-k:以那个区间来进行排序
范例二:/etc/passwd 内容是以 : 来分隔的,我想以第三栏来排序,该如何?
[root@www ~]# cat /etc/passwd | sort -t ‘:’ -k 3
- uniq
范例一:使用 last 将账号列出,仅取出账号栏,进行排序后仅取出一位;
[root@www ~]# last | cut -d ’ ’ -f1 | sort | uniq
- wc
-l:列出行
-w:列出字
-m:列出字符
范例二:我知道使用 last 可以输出登陆者,但是 last 最后两行并非账号内容,
那么请问,我该如何以一行命令串取得这个月份登陆系统的总人次?
[root@www ~]# last | grep [a-zA-Z] | grep -v ‘wtmp’ | wc -l
- 双向重导向:tree
[root@www ~]# ls -l / | tee -a ~/homefile | more
要注意! tee 后接的文件会被覆盖,若加上 -a 这个选项则能将信息累加。
- tr删除一段信息
-d:删除信息中字符串
-s:取代重新字符
范例一:将 last 输出的信息中,所有的小写变成大写字符:
[root@www ~]# last | tr ‘[a-z]’ ‘[A-Z]’
# 事实上,没有加上单引号也是可以运行的,如:『 last | tr [a-z] [A-Z] 』
范例二:将 /etc/passwd 输出的信息中,将冒号 (:) 删除
[root@www ~]# cat /etc/passwd | tr -d ‘:’
范例三:将 /etc/passwd 转存成 dos 断行到 /root/passwd 中,再将 ^M 符号删除
[root@www ~]# cp /etc/passwd /root/passwd && unix2dos /root/passwd
- col
-x:将tab键转换成对等的空格键
-b:在文字内有反斜杠(/)时,仅保留反斜杠最后接的那个字符
- paste
-d:后面接分隔符,默认是[tab]分隔符
:如果file部分携程-,表示来自si的数据
范例二:先将 /etc/group 读出(用 cat),然后与范例一贴上一起!且仅取出前三行
[root@www ~]# cat /etc/group|paste /etc/passwd /etc/shadow -|head -n 3
- expand[unexpand]
将tab转换成空格。
^I是制表符tab
范例三:承上,我将 [tab] 按键配置成 6 个字符的话?
[root@www ~]# grep ‘^MANPATH’ /etc/man.config | head -n 3 | \
expand -t 6 - | cat -A
- split
-b:后面可接分割成文件大小。可加单位b,k,m。
-l:以行数进行分割
PREFIX:分割文件的前导文字
范例一:我的 /etc/termcap 有七百多K,若想要分成 300K 一个文件时?
[root@www ~]# cd /tmp; split -b 300k /etc/termcap termcap
[root@www tmp]# ll -k termcap*
[root@www tmp]# cat termcap* >> termcapback
范例三:使用 ls -al / 输出的信息中,每十行记录成一个文件
[root@www tmp]# ls -al / | split -l 10 - lsroot
[root@www tmp]# wc -l lsroot*
- 关于减号-的用途
stdin 与 stdout 可以利用减号 “-” 来替代
[root@www ~]# tar -cvf - /home | tar -xvf -
我将 /home 里面的文件给他打包,但打包的数据不是纪录到文件,而是传送到 stdout; 经过管线后,将 tar -cvf - /home 传送给后面的 tar -xvf - 』。后面的这个 - 则是取用前一个命令的 stdout
- script
1.
\#!/bin/bash
\# Program:
\# This program shows "Hello World!" in your screen.
\# History:
\# 2005/08/23 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
2.
filename=${fileuser:-"filename"}
# 开始判断有否配置档名
date2=$(date --date='1 days ago' +%Y%m%d)
# 前一天的日期
date3=$(date +%Y%m%d)
# 今天的日期
file1=${filename}${date1}
# 底下三行在配置档名
3.
[root@www scripts]# echo $(( 13 % 3 ))
4.source ~/.bashrc
在父程序中运行子程序
Script判断式
-
- test判断
-e f d 档名文件目录判断
-r w x 可读可写可执行判断
-nt ot ef 新旧同一个inode判断
- 整数值判断
-eq ne == !=
gt lt > <
ge le >= <=
- 字符串判断
-z string 字符串为空,返回true
n string 字符串为空,返回false
str1 = str2 相等,返回true
str1 != str2 不相等,返回flase
- 多重条件判断
-a 同时成立 eg: test -r file -a -x file 返回true
-o 任何一个成立,test -r file o -x file
! 反相状态,test ! -x file
利用判断符号 []
[root@www ~]# [ -z “ HOME"];echo ?
ps:[]里面都需要有空格,[]就等于test,多用于if….then…fi
默认变量( 0, 1,$2)
`
#` :代表后接的参数『个数』,以上表为例这里显示为『 4 』;
` @` :代表`『 “
1”“ 2” “
3”“ 4” 』`之意,每个变量是独立的(用双引号括起来); `
∗‘:代表‘『“ 1c
2c 3c
4”』‘,其中c为分隔字节,默认为空白键,所以本例中代表‘『“ 1
2 3 $4” 』`之意。 - shift n 参数变量号码偏移 - 条件判断式 `if [ ];then esif [];then else fi`
- netstat -tuln查询主机开启的服务(0.0.0.0或:::代表对整个internet开放)
80: WWW
22: ssh
21: ftp
25: mail
111: RPC(远程程序呼叫)
631: CUPS(列印服务功能)
testing=$(netstat -tuln | grep ":80 ") # 侦测看 port 80 在否?1
if [ "$testing" != "" ]; then
echo "WWW is running in your system."
fi
# 2. 测试一下,这个输入的内容是否正确?利用正规表示法罗~
date_d=$(echo $date2 |grep '[0-9]\{8\}')
# 看看是否有八个数字
if [ "$date_d" == "" ]; then
echo "You input the wrong date format...."
exit 1
fi
# 3. 开始计算日期罗~
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)) # 转为日数
if [ "$date_total_s" -lt "0" ]; then # 判断是否已退伍
echo "You had been demobilization before: " $((-1*$date_d)) " ago"
交互式
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
function
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
回圈(loop)
不定loop
while [ "$yn" != "yes" -a "$yn" != "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done
until [ "$yn" == "yes" -o "$yn" == "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done
固定loop
users=$(cut -d ':' -f1 /etc/passwd) # 撷取帐号名称
for username in $users # 开始回圈进行!
do
id $username
finger $username
done
for …do…done的数值处理
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"
shell script的追踪与debug
[root@www ~]# sh [-nvx] scripts.sh
选项与参数:
-n :不要运行 script,仅查询语法的问题;
-v :再运行 sccript 前,先将 scripts 的内容输出到萤幕上;
-x :将使用到的 script 内容显示到萤幕上,这是很有用的参数!
- 更新记录
- 2016年02月02日 version v1.0
- 应用command模块
- bash script模块