[No000014A]Linux简介与shell编程
Linux 介绍
内核
库: .so 共享对象,windows:dll 动态链接库
应用程序
Linux的基本原则:
1、由目的单一的小程序组成;组合小程序完成复杂任务;
2、一切皆文件;
3、尽量避免捕获用户接口;
4、配置文件保存为纯文本格式;
用户接口
GUI接口:
CLI接口:
命令提示符,prompt, bash(shell)
#: root
$: 普通用户
命令:
命令格式:
命令 选项 参数
选项:
短选项: -
多个选项可以组合:-a -b = -ab
长选项: --
参数:命令的作用对象
虚拟终端(terminal):Ctrl+Alt+F1-F6
Shell:
GUI: Graphic User Interface
Windows
X-Window
Gnome
KDE
Xface
CLI: Command Line Interface
sh
bash
csh
ksh
zsh
tcsh
prompt,命令提示符:
命令:
magic number: 魔数
shebang
#!/bin/bash
# command options... arguments...
选项:
短选项 -
长选项 --
参数:
list: ls
列出,列表
目录:文件,路径映射
路径:从指定起始点到目的地所经过位置
文件系统:file system
列出指定路径下的文件
目录:working directory, current directory
pwd: Printing Working directory
ls
-l:长格式
文件类型:
-:普通文件 (f)
d: 目录文件
b: 块设备文件 (block)
c: 字符设备文件 (character)
l: 符号链接文件(symbolic link file)
p: 命令管道文件(pipe)
s: 套接字文件(socket)
文件权限:9位,每3位一组,3组 权限(U,G,O)每一组:rwx(读,写,执行), r-- ,第一组:文件的属主用户权限。第二组:文件的属组用户权限,第三组:其他用户权限
文件硬链接的次数
文件的属主(owner)
文件的属组(group)
文件大小(size),单位是字节
时间戳(timestamp):最近一次被修改的时间
访问:access
修改:modify,文件内容发生了改变
改变:change,metadata,元数据
-h:做单位转换
-a: 显示以.开头的隐藏文件
. 表示当前目录
.. 表示父目录
-A
-d: 显示目录自身属性
-i: index node, inode
-r: 逆序显示
-R: 递归(recursive)显示
cd: change directory
家目录,主目录, home directory
cd ~USERNAME: 进入指定用户的家目录
cd -:在当前目录和前一次所在的目录之间来回切换
命令类型:
内置命令(shell内置),内部,内建
外部命令:在文件系统的某个路径下有一个与命令名称相应的可执行文件
type: 显示指定属于哪种类型
date:时间管理
Linux: rtc
硬件时钟
系统时钟
获得命令的使用帮助:
内部命令:
help COMMAND 比如:help cd
外部命令:
COMMAND --help 比如:date --help
命令手册:manual
man COMMAND
whatis COMMAND
分章节:
1:用户命令(/bin, /usr/bin, /usr/local/bin)
2:系统调用
3:库用户
4:特殊文件(设备文件)
5:文件格式(配置文件的语法)
6:游戏
7:杂项(Miscellaneous)
8: 管理命令(/sbin, /usr/sbin, /usr/local/sbin)
MAN:
NAME:命令名称及功能简要说明
SYNOPSIS:用法说明,包括可用的选项
DESCRIPTION:命令功能的详尽说明,可能包括每一个选项的意义
OPTIONS:说明每一个选项的意义
FILES:此命令相关的配置文件
BUGS:
EXAMPLES:使用示例
SEE ALSO:另外参照
翻屏:
向后翻一屏:SPACE
向前翻一屏:b
向后翻一行:ENTER
向前翻一行:k
查找:
/KEYWORD: 向后
n: 下一个
N:前一个
q: 退出
练习:
使用date单独获取系统当前的年份、月份、日、小时、分钟、秒
hwclock
-w:
-s:
练习:
1、echo是内部命令还是外部命令?
2、其作用?
3、如何显示 echo "The year is 2013." echo "Today is 26."为两行?
请设置系统时间和硬件时间保持一致。
cp
mv
文件系统:
rootfs: 根文件系统 /
FHS:Linux
/boot: 系统启动相关的文件,如内核、initrd,以及grub(bootloader)
/dev: 设备文件
设备文件:
块设备:随机访问,数据块
字符设备:线性访问,按字符为单位
设备号:主设备号(major)和次设备号(minor)
/etc:配置文件
/home:用户的家目录,每一个用户的家目录通常默认为/home/USERNAME
/root:管理员的家目录;
/lib:库文件
静态库, .a
动态库, .dll, .so (shared object)
/lib/modules:内核模块文件
/lib64
/media:挂载点目录,移动设备
/mnt:挂载点目录,额外的临时文件系统
/opt:可选目录,第三方程序的安装目录
/proc:伪文件系统,内核映射文件
/sys:伪文件系统,跟硬件设备相关的属性映射文件
/tmp:临时文件, /var/tmp
/var:可变化的文件
/bin: 可执行文件, 用户命令
/sbin:管理命令
绝对路径:以跟目录为起点到目标的路径。
相对路径:以当前目录为起点到目标的路径
mkdir:创建空目录
-p:
-v: verbose
/root/x/y/z
/mnt/test/x/m,y
mkdir -pv /mnt/test/x/m /mnt/test/y
mkdir -pv /mnt/test/{x/m,y}
# tree:查看目录树
删除目录:rmdir (remove directory)
删除空目录
-p
文件创建和删除
# touch
-a
-m
-t
-c
# stat 查看文件信息
创建文件,可以使用文件编辑器
nano
vi(另外一个文件)
删除文件:rm
-i 删除之前确认
-f 删除之前不确认
-r 递归删除
rm -rf / linux 自杀
cp: copy
cp SRC DEST
-r
-i 存在覆盖前确认
-f
-p
-a:归档复制,常用于备份
cp file1 file2 file3
一个文件到一个文件
多个文件到一个目录
cp /etc/{passwd,inittab,rc.d/rc.sysinit} /tmp/
mv: move
移动文件
mv SRC DEST
mv -t DEST SRC
目录管理:
ls、cd、pwd、mkdir、rmdir、tree
文件管理:
touch、stat、file、rm、cp、mv、nano,vi,vim
日期时间:
date、clock、hwclock、cal ,ntpdate
查看文本:
cat、tac、more、less、head、tail
分屏显示:
more、less
more: 向后翻
less:
head:查看前n行
tail:查看后n行
-n
tail -f: 查看文件尾部,不退出,等待显示后续追加至此文件的新内容;
文本处理:
cut、sort,join、sed、awk
文本文件:
Tom:23:male:2013/05/06
cut:
-d: 指定字段分隔符,默认是空格
-f: 指定要显示的字段
-f 1,3
-f 1-3
文本排序:sort
-n:数值排序
-r: 降序
-t: 字段分隔符
-k: 以哪个字段为关键字进行排序
-u: 排序后相同的行只显示一次
-f: 排序时忽略字符大小写
文本统计:wc (word count)
-l
-w
-c
-L
sed基本用法:
sed: Stream EDitor
行编辑器 (全屏编辑器: vi)
sed: 模式空间
默认不编辑原文件,仅对模式空间中的数据做处理;而后,处理结束后,将模式空间打印至屏幕;
sed [options] 'AddressCommand' file ...
-n: 静默模式,不再默认显示模式空间中的内容
-i: 直接修改原文件
-e SCRIPT -e SCRIPT:可以同时执行多个脚本
-f /PATH/TO/SED_SCRIPT
sed -f /path/to/scripts file
-r: 表示使用扩展正则表达式
Command:
d: 删除符合条件的行;
p: 显示符合条件的行;
a \string: 在指定的行后面追加新行,内容为string
\n:可以用于换行
i \string: 在指定的行前面添加新行,内容为string
r FILE: 将指定的文件的内容添加至符合条件的行处
w FILE: 将地址指定的范围内的行另存至指定的文件中;
s/pattern/string/修饰符: 查找并替换,默认只替换每行中第一次被模式匹配到的字符串
加修饰符
g: 全局替换
i: 忽略字符大小写
s///: s###, s@@@
\(\), \1, \2
l..e: like-->liker
love-->lover
like-->Like
love-->Love
&: 引用模式匹配整个串
sed练习:
1、删除/etc/grub.conf文件中行首的空白符;
sed -r 's@^[[:space:]]+@@g' /etc/grub.conf
2、替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5;
sed 's@\(id:\)[0-9]\(:initdefault:\)@\15\2@g' /etc/inittab
3、删除/etc/inittab文件中的空白行;
sed '/^$/d' /etc/inittab
awk:
awk是一个强大的文本分析工具,
相对于grep的查找,sed的编辑,
awk在其对数据分析并生成报告时,显得尤为强大。
简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk '{pattern + action}' {commands}
其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。
花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。
pattern就是要表示的正则表达式,用斜杠括起来。
案例:
显示最近登录的5个帐号
#last -n 5 | awk '{print $1}'
读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域
$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键" 或 "[tab]键",
所以$1表示登录用户,$3表示登录用户ip,以此类推。
如果只是显示/etc/passwd的账户
#cat /etc/passwd |awk -F ':' '{print $1}'
root
daemon
bin
sys
这种是awk+action的示例,每行都会执行action{print $1}。
-F指定域分隔符为':'。
如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割
#cat /etc/passwd |awk -F ':' '{print $1"\t"$7}'
root /bin/bash
daemon /bin/sh
bin /bin/sh
sys /bin/sh
如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在所有行添加列名name,shell,在最后一行添加"blue,/bin/nosh"。
复制代码
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'
name,shell
root,/bin/bash
daemon,/bin/sh
bin,/bin/sh
sys,/bin/sh
....
blue,/bin/nosh
awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。
搜索/etc/passwd有root关键字的所有行
#awk -F: '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)。
搜索支持正则,例如找root开头的: awk -F: '/^root/' /etc/passwd
搜索/etc/passwd有root关键字的所有行,并显示对应的shell
# awk -F: '/root/{print $7}' /etc/passwd
/bin/bash
这里指定了action{print $7}
awk内置变量
awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
$0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。
统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:
#awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh
使用printf替代print,可以让代码更加简洁,易读
awk -F ':' '{printf("filename:%s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
print和printf
awk中同时提供了print和printf两种打印输出的函数。
其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。
printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。
awk编程
变量和赋值
除了awk的内置变量,awk还可以自定义变量。
下面统计/etc/passwd的账户人数
awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
......
user count is 40
count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。
这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0:
awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd
[start]user count is 0
root:x:0:0:root:/root:/bin/bash
...
[end]user count is 40
统计某个文件夹下的文件占用的字节数
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
[end]size is 8657198
如果以M为单位显示:
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'
[end]size is 8.25889 M
注意,统计不包括文件夹的子目录。
条件语句
awk中的条件语句是从C语言中借鉴来的,见如下声明方式:
复制代码
if (expression) {
statement;
statement;
... ...
}
if (expression) {
statement;
} else {
statement2;
}
if (expression) {
statement1;
} else if (expression1) {
statement2;
} else {
statement3;
}
统计某个文件夹下的文件占用的字节数,过滤4096大小的文件(一般都是文件夹):
ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}'
[end]size is 8.22339 M
循环语句
awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同。
数组
因为awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。
显示/etc/passwd的账户
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
0 root
1 daemon
2 bin
3 sys
4 sync
5 games
......
这里使用for循环遍历数组
linux 引号
1、反引号:`` ,命令替换
2、单引号:'' ,字符串
3、双引号: "" ,变量替换
管道:前一个命令的输出,作为后一个命令的输入
命令1 | 命令2 | 命令3 | ...
练习:
1、统计/usr/bin/目录下的文件个数;
# ls /usr/bin | wc -l
判断 /home/goldin目录是否有文件
2、取出当前系统上所有用户的shell,要求,每种shell只显示一次,并且按顺序进行显示;
# cut -d: -f7 /etc/passwd | sort -u
4、取出/etc/inittab文件的第6行;
# head -6 /etc/inittab | tail -1
5、取出/etc/passwd文件中倒数第9个用户的用户名和shell,显示到屏幕上并将其保存至/tmp/users文件中;
# tail -9 /etc/passwd | head -1 | cut -d: -f1,7 | tee /tmp/users
6、显示/etc目录下所有以pa开头的文件,并统计其个数;
# ls -d /etc/pa* | wc -l
用户管理:
useradd, userdel, usermod, passwd, chsh, chfn, finger, id, chage
组管理:
groupadd, groupdel, groupmod, gpasswd
权限管理:
chown, chgrp, chmod, umask
/etc/passwd:
用户名:密码:UID:GID:注释:家目录:默认SHELL
/etc/group:
组名:密码:GID:以此组为其附加组的用户列表
/etc/shadow:
用户名:密码:最近一次修改密码的时间:最短使用期限:最长使用期限:警告时间:非活动时间:过期时间:
用户管理:
useradd, userdel, usermod, passwd, chsh, chfn, finger, id, chage
useradd [options] USERNAME
-u UID
-g GID(基本组)
-G GID,... (附加组)
-c "COMMENT"
-d /path/to/directory
-s SHELL
-m -k
-M
-r: 添加系统用户
userdel:
userdel [option] USERNAME
-r: 同时删除用户的家目录
id:查看用户的帐号属性信息
-u
-g
-G
-n
finger: 查看用户帐号信息
finger USERNAME
修改用户帐号属性:
usermod
-u UID
-g GID
-a -G GID:不使用-a选项,会覆盖此前的附加组;
-c
-d -m:
-s
-l
-L:锁定帐号
-U:解锁帐号
chsh: 修改用户的默认shell
chfn:修改注释信息
密码管理:
passwd [USERNAME]
--stdin
-l
-u
-d: 删除用户密码
pwck:检查用户帐号完整性
组管理:
创建组:groupadd
groupadd
-g GID
-r:添加为系统组
groupmod
-g GID
-n GRPNAME
groupdel
gpasswd:为组设定密码
newgrp GRPNAME <--> exit
chage
-d: 最近一次的修改时间
-E: 过期时间
-I:非活动时间
-m: 最短使用期限
-M: 最长使用期限
-W: 警告时间
权限管理:
r:
w:
x:
111 101 101
三类用户:
u: 属主
g: 属组
o: 其它用户
chown: 改变文件属主(只有管理员可以使用此命令)
# chown USERNAME file,...
-R: 修改目录及其内部文件的属主
--reference=/path/to/somefile file,...
chown USERNAME:GRPNAME file,...
chown USERNAME.GRPNAME file,...
# chgrp GRPNAME file,...
-R
--reference=/path/to/somefile file,...
chmod: 修改文件的权限
修改三类用户的权限:
chmod MODE file,...
-R
--reference=/path/to/somefile file,...
rwxr-x---
ps -aux
netstat -ntpl
grep
find
yum install lrzsz 上传文件rz
-linux 安全性
登陆
等日志查看
限制某些IP才能ssh登陆
...
密码一个月换一次
设置密码:特殊符号,大写,小写,1223455,最少8位
防火墙
规则
添加规则
配置文件
软件安装和管理
软件包
1、bin文件.bin
2、rpm包
3、源码压缩包
安装软件的步骤:
1、检查是否已经安装
rpm -qa | grep jdk
2、下载软件包
3、安装
依赖
rpm 包,已经编译之后的应用程序。
rpm命令:
1、安装
rpm -i /PATH/TO/PACKAGE_FILE
-h: 以#显示进度;每个#表示2%;
-v: 显示详细过程
-vv: 更详细的过程
rpm -ivh /PATH/TO/PACKAGE_FILE
--nodeps: 忽略依赖关系;
--replacepkgs: 重新安装,替换原有安装;
--force: 强行安装,可以实现重装或降级;
安装jdk
配置环境变量:编辑/etc/profile 或者 ~/.bash_profile
export JAVA_HOME=/usr/java/jdk1.7.0_71
export PATH=$PATH:$JAVA_HOME/bin
2、查询
rpm -q PACKAGE_NAME: 查询指定的包是否已经安装
rpm -qa : 查询已经安装的所有包
rpm -qi PACKAGE_NAME: 查询指定包的说明信息;
rpm -ql PACKAGE_NAME: 查询指定包安装后生成的文件列表;
rpm -qc PACEAGE_NEME:查询指定包安装的配置文件;
rpm -qd PACKAGE_NAME: 查询指定包安装的帮助文件;
rpm -q --scripts PACKAGE_NAME: 查询指定包中包含的脚本
rpm -qf /path/to/somefile: 查询指定的文件是由哪个rpm包安装生成的;
如果某rpm包尚未安装,我们需查询其说明信息、安装以后会生成的文件;
rpm -qpi /PATH/TO/PACKAGE_FILE
rpm -qpl
3、升级
rpm -Uvh /PATH/TO/NEW_PACKAGE_FILE: 如果装有老版本的,则升级;否则,则安装;
rpm -Fvh /PATH/TO/NEW_PACKAGE_FILE:如果装有老版本的,则升级;否则,退出;
--oldpackage: 降级
4、卸载
rpm -e PACKAGE_NAME
--nodeps
5、校验
rpm -V PACKAGE_NAME
6、重建数据库
rpm
--rebuilddb: 重建数据库,一定会重新建立;
--initdb:初始化数据库,没有才建立,有就不用建立;
7、检验来源合法性,及软件包完整性;
加密类型:
对称:加密解密使用同一个密钥
公钥:一对儿密钥,公钥,私钥;公钥隐含于私钥中,可以提取出来,并公开出去;
单向:
# ls /etc/pki/rpm-gpg/
RPM-GPG-KEY-redhat-release
rpm -K /PAPT/TO/PACKAGE_FILE
dsa, gpg: 验正来源合法性,也即验正签名;可以使用--nosignature,略过此项
sha1, md5: 验正软件包完整性;可以使用--nodigest,略过此项
yum: Yellowdog Update Modifier
yum
apt-get
yum install zsh
yum源配置
[Repo_ID]
name=Description
baseurl=
ftp://
http://
file:///
enabled={1|0}
gpgcheck={1|0}
gpgkey=
yum [options] [command] [package ...]
-y: 自动回答为yes
--nogpgcheck
list: 列表
支持glob
all
available:可用的,仓库中有但尚未安装的
installed: 已经安装的
updates: 可用的升级
clean: 清理缓存
[ packages | headers | metadata | dbcache | all ]
repolist: 显示repo列表及其简要信息
all
enabled: 默认
disabled
install: 安装
yum install PACKAGE_NAME
update: 升级
update_to: 升级为指定版本
remove|erase:卸载
info:
provides| whatprovides: 查看指定的文件或特性是由哪个包安装生成的;
groupinfo
grouplist
groupinstall
groupremove
groupupdate
手动编译安装
源码安装步骤:
1、下载
2、查看源码
3、准备编译环境
4、检查(依赖,兼容),预编译
5、编译
6、安装
tar
gcc: GNU C Complier, C
g++:
make
make install
编译安装的三步骤:
前提:准备开发环境(编译环境)
安装"Development Tools"和"Development Libraries"
yum groupinstall Development Tools Development Libraries
tar -zxvf 压缩包 ,tar.gz
# tar
# cd
# ./configure
--help
--prefix=/path/to/somewhere
--sysconfdir=/PATH/TO/CONFFILE_PATH
功能:1、让用户选定编译特性;2、检查编译环境;
# make
# make install
# tar xf tengine-1.4.2.tar.gz
# cd tegnine-1.4.2
# ./configure --prefix=/usr/local/tengine --conf-path=/etc/tengine/tengine.conf
# make
# make install
安装apache
解压:tar -zxvf httpd-2.4*****.tar.gz
apache 依赖apr,和apr-util
下载安装apr和apr-util
使用源码安装mysql
Shell编程
shell :弱类型、 解释型语言
解释器:bash
一、变量
bash的变量类型:
环境变量
本地变量(局部变量)
位置变量
特殊变量:bash内置的用来保存某些特殊数据的变量。(也叫系统变量)
本地变量:只属于某一个bash的变量。
var_name=值
作用域:整个bash进程
局部变量:
local var_name =值,
作用域:当前代码段。
环境变量:
export 名字=值
作用域:当前的shell和其子shell。
注意:脚本在执行时都会启动一个子shell进程:
命令行中启动的脚本会继承当前shell环境变量。
系统自动启动脚本(非命令行启动):则需要自我定义环境变量。
位置变量: 用于 脚本执行的参数,$1 表示第一个参数,以此类推
$1,$2….
特殊变量:
$? :上一个命令的执行状态返回值。
$# 传递到脚本的参数个数
$* 传递到脚本的参数,与位置变量不同,此选项参数可超过9个
$$ 脚本运行时当前进程的ID号,常用作临时变量的后缀,如 haison.$$
$! 后台运行的(&)最后一个进程的ID号
$@ 与$#相同,使用时加引号,并在引号中返回参数个数
$- 上一个命令的最后一个参数
$? 最后命令的退出状态,0表示没有错误,其他任何值表明有错误
程序有两类返回值:
1、 执行结果
2、 执行状态,$? : 0:表示正确,1-255:错误
输出重定向:
>覆盖重定向
>> 追加重定向
2> 错误覆盖重定向
2>>错误追加重定向
&> 全部重定向
撤销变量:
unset 变量名
查看shell中变量:
set 命令
查看shell中的环境变量
printenv
env
export
引用变量:${变量名},一般可以省略{}
单引号:强引用,不作变量替换
双引号:弱引用,做变量替换
反引号:``命令替换
二、脚本
脚本:命令的堆砌。
练习:写一个脚本,完成以下任务。
1、 添加5个用户,user1,,,,user5
2、 每个用户的密码同用户名,要求:添加密码完成后不显示passwd执行结果。
3、 显示添加成功信息
练习2:写一个脚本,完成以下任务。
1、 使用一个变量保存一个用户名
2、 删除此变量中的用户,且一并删除其家目录
3、 显示"用户删除成功"信息。
条件判断:
条件表达式:
1、 [ expression ]
2、 test expression
整数比较:
-eq : 比如:[ $A –eq $B ]
-ne , -gt ,-lt,-ge,-le
命令的逻辑关系:
在linux 中 命令执行状态:0 为真,其他为假
逻辑与: &&
第一个条件为假时,第二条件不用再判断,最终结果已经有;
第一个条件为真时,第二条件必须得判断;
逻辑或: ||
逻辑非: !
命令执行的状态 的逻辑关系
1、如果用户user6不存在则添加用户6
! id user6 && useradd user6
Id user6 || useradd user6
2、如果用户不存在,添加用户并显示添加成功,否则显示其已存在
3、如果/etc/inittab文件的行数大于50,就显示好大的文件;
练习:
1、 添加3个用户user1.user3,并且设置密码和用户名相同,如果用户已经存在,显示:已存在
2、 添加完成之后计算系统一共有多个用户。
练习:给定一个用户,
1、 如果其UID=0,就显示其为管理员,否则显示其为普通用户
备注:
passwd默认是要用终端作为标准输入,加上--stdin表示可以用任意文件做标准输入
于是这里用管道作为标准输入
条件判断,控制结构:
If 条件 ;then
语句
elif 条件 ; then
语句
else
语句
fi
-a : 逻辑与,并且 : if [ $# -gt 1 –a $# -lt 3 –o $# -eq 2 ] ; then
-o :或者 比如:
练习:判断命令历史中历史命令的总条目大于500,如果大于,则显示"Some command is done.",否则显示:"OR"。
练习:给定三个整数,判断其中的最大值和最小数。并显示出来
bash -n shell文件 :检查文件是否有语法错误。
bash –x shell 文件 :debug 执行文件
Shell 中如何算术运算
1、 let 算术运算表达式
let C=$A + $B
2、$[算术表达式]
C = $[$A+$B]
3、$((算术表达式))
C=$(($A+$B))
3、 expr 算术表达式 ,注意:表达式中各操作数及运算符之间要有空格。而且要使用命令引用
C=`expr $A + $B`
练习:给定一个用户,获取其密码警告期限,然后判断用户密码使用期限是否已经小于警告期限,如果小于,则是显示"WARN" ,否则显示密码还有多少天到期。
提示:date +%s :今天的秒数
Cat /etc/shadow 密码时间。
exit : 退出脚本
退出脚本可以指定脚本执行的状态:exit 0 。
复习:
测试方法:
[ 表达式 ]
[[ 表达式 ]]
test 表达式
INT1=33
INT2=32
[ $INT1 -eq $INT2 ]
[[ $INT1 -eq $INT2 ]]
test $INT1 -eq $INT2
文件测试: [ ] 需要中括号
-e FILE :测试文件是否存在
-f FILE :测试文件是否为普通文件
-d FILE :测试文件是否为目录
-r 权限
-w
-x
特殊变量:
$# $@
字符串测试:
== 等号两端需要空格
!=
-n string : 判断字符串是否为空
-s string : 判断字符串是否不空
练习:指定一个用户名,判断此用户的用户名和它的基本组 组名是否相同.
#!/bin/bash
if ! id $1 &>/dev/null ; then
echo "No such user."
exit 12
fi
if [ $1 == `id –n –g $1` ] ;then
echo "xiangtong"
else
echo "bu xiangtong"
fi
练习: 判断当前主机的CPU生产商,(其信息保存在/proc/cupinfo文件中)。
如果是:AuthemticAMD ,就显示其为AMD公司
GenuineIntel ,就显示其为 Intel公司
否则,就显示其为非主流公司。
练习:将那些可以登录的用户查询出来,并且将用户的帐号信息提取出来,后放入/tmp/test.txt文件中,并给定行号。在行首。
循环:进入条件,退出条件
for 变量 in 列表 ; do
语句
done
比如: for I in 1 2 3 4 5 ;do
语句
done、
如何生成列表:
1、{1..100}
2、seq [起始数] [跨度数] 结束数
3、ls /etc 文件列表
练习:依次向/etc/passwd中的每个用户问好:hello 用户名,并显示用户的shell:
Hello ,root ,your shell :/bin/bash。
2、 只向默认shell为bash的用户问好。
While 循环
格式一
while 条件;do
语句
[break]
done
格式二 死循环
while true
do
语句
done
格式三 死循环
while :
do
语句
done
格式四 死循环
while [ 1 ]
do
语句
done
格式五 死循环
while [ 0 ]
do
语句
done
练习:计算100以内所有能被3整除的整数的和
练习:使用echo输出10个随机数,并且一行显示。提示:$RANDOM
练习:传给脚本一个参数:目录,输出该目录中文件最大的,文件名和文件大小:
比如:1.txt 100KB
ls -l | awk '{print $5,$9}' | sort -nr
2、查看该目录下是否有大小为0的文件,如果有则删除。同时显示删除信息。
练习:查询当前192.168.1.x网段内,那些IP被使用了,输出这些IP到一个文件中。
练习:请根据一个关键字,杀掉系统进程中包含此关键字的进程。
echo –n $RANDOM
case 语句
case 变量 in
value1)
语句
;;
value2)
语句
;;
*)
语句
;;
esac
Linux "ls -l"文件列表权限详解
1.使用 ls -l 命令 执行结果如下(/var/log) :
drwxr-x--- 2 root adm 4096 2013-08-07 11:03 apache2
drwxr-xr-x 2 root root 4096 2013-08-07 09:43 apparmor
drwxr-xr-x 2 root root 4096 2013-08-07 09:44 apt
-rw-r----- 1 syslog adm 16802 2013-08-07 14:30 auth.log
-rw-r--r-- 1 root root 642 2013-08-07 11:03 boot.log
drwxr-xr-x 2 root root 4096 2013-08-06 18:34 ConsoleKit
drwxr-xr-x 2 root root 4096 2013-08-07 09:44 cups
-rw-r----- 1 syslog adm 10824 2013-08-07 11:08 daemon.log
drwxr-xr-x 2 root root 4096 2013-08-07 09:45 dbconfig-common
-rw-r----- 1 syslog adm 21582 2013-08-07 11:03 debug
drwxr-xr-x 2 root root 4096 2013-08-07 09:45 dist-upgrade
-rw-r--r-- 1 root adm 59891 2013-08-07 11:03 dmesg
展示结果大体分为七列(部分) :
以第一条记录为例
第一列 : “drwxr-x---” 表识文件的类型 和文件权限
第二列: “2”是纯数字 ,表示 文件链接个数
第三列 : “root” 表示文件的所有者
第四列:“adm” 表示为文件的所在群组
第五列:“4096”,表示为文件长度(大小)
第六列:“2013-08-07 11:03”,表示文件最后更新(修改)时间
第七列:“apache2” 表示文件的名称
详见下图:
2.文件类型和文件权限 ,即为列表第一列内容:(以第一条记录为例 )
“drwxr-x---” 含义:有两部分组成 ,一部分是第一列即为“d” ,表示文件类型(目录或文件夹),另一部分是“rwxr-x---” 表示文件权限,权限有分为三段:即为 “ rwx ”,“ r-x ”和 “ --- ”分别表示 ,文件所有者的权限,文件所属组的权限 和其他用户对文件的权限。
(1)文件类型,大体分为如下几类 :
d :目录
- :文件
l :链接
s :socket
p :named pipe
b :block device
c :character device
(2)文件权限 :
r :含义为 “可读”,用数字 4 表示
w:含义为 “可写”用数字 2 表示
X(小X):含义为“可执行”用数字 1 表示
-:含义为“无权限”用数字0 表示
X (大X):含义为只有目标文件对某些用户是可执行的或该目标文件是目录时才追加x 属性。
s:含义为 在文件执行时把进程的属主或组ID置为该文件的文件属主。方式“u+s”设置文件的用 户ID位,“g+s”设置组ID位。
t :含义为保存程序的文本到交换设备上
3.文件权限的更改 :
使用命令 :chmod 文件权限 文件名称 [-R]
命令两种用法 :
(1)直接给文件赋相应的权限即为 :
chmod a+x auth.log #含义为 给 auth.log 文件赋予所有者可执行权限
(2)使用数字方式代替权限 :
例如 :
chmod 777 auth.log #含义为给auth.log文件赋予任何可读,可写,可执行权限
数字含义详见如下列表:
所有者 群组 其他 三位代表权限的数字
r w x rwx rwx 实际结果
4 2 1 421 421 777
4 2 1 4 0 1 4 0 1 705
4.文件所有者的更改 :
命令 chown 用户名 文件,例如 :
chmod mysql auth.log #含义为 把 文件 auth.log 的所有者更改为 mysql
5.文件所在组的更改
命令 chgrp [-R] 群组名称 文件名称
例如 :
chgrp -R mysql apache2 #含义为 ,把 目录apache2 的所在组更改为mysql
ubuntu 修改bash命令行提示符
使用命令行的时候有时候输出较多的话,找上一条输入的命令都不好找,每条命令之前的分割线不是很明显,好在可以通过修改家目录的~/.bashrc文件中的PS1的值来达到修改Bash命令行提示符的颜色的目的,通过修改PS1还可以修改提示的工作目录的长度。
$ vim ~/.bashrc
在最后一行添加如下的代码:
PS1='\[\033[0;32m\]<\u@\h \W>\$\[\033[0m\]'
export PS1
然后通过命令:
$ source .bashrc
使更改立即生效;
效果如下:
PS1被用作主要的提示字符串使用:
相关特殊字符
\H: #完整的主机名称。
\h: #仅取主机的第一个名字,到“.”结束
\u: #当前用户的用户名
\w: #完整的工作目录名称。宿主目录(如/hom/peter)会以~代替
\W: #利用basename取得工作目录名称,所以只会列出最后一个目录
\$: #提示字符,如果是root时,提示符为:#,普通用户则为:
\#: #显示命令的编号(如30,31...)
\t: 显示时间为24小时格式,如:HH:MM:SS
\T: #显示时间为12小时格式
\A: #显示时间为24小时格式: HH:MM
\d: #代表日期,格式为weekday month date, 例如:"Tue May 26"
\v: #bash的版本信息 (如4.3)