Linux
Linux
Linux系统基本
Linux系统目录结构
以下是对这些目录的解释:
/bin:
bin是Binary的缩写, 这个目录存放着最经常使用的命令。/boot:
这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件。/dev :
dev是Device(设备)的缩写, 该目录下存放的是Linux的外部设备,在Linux中访问设备的方式和访问文件的方式是相同的。/etc:
这个目录用来存放所有的系统管理所需要的配置文件和子目录。/home:
用户的主目录,在Linux中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的。/lib:
这个目录里存放着系统最基本的动态连接共享库,其作用类似于Windows里的DLL文件。几乎所有的应用程序都需要用到这些共享库。/lost+found:
这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。/media linux系统会自动识别一些设备,例如U盘、光驱等等,当识别后,linux会把识别的设备挂载到这个目录下。
/mnt:
系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在/mnt/上,然后进入该目录就可以查看光驱里的内容了。/opt:
这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。/proc:
这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。
这个目录的内容不在硬盘上而是在内存里,我们也可以直接修改里面的某些文件,比如可以通过下面的命令来屏蔽主机的ping命令,使别人无法ping你的机器:echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
/root:
该目录为系统管理员,也称作超级权限者的用户主目录。/sbin:
s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。/selinux:
这个目录是Redhat/CentOS所特有的目录,Selinux是一个安全机制,类似于windows的防火墙,但是这套机制比较复杂,这个目录就是存放selinux相关的文件的。/srv:
该目录存放一些服务启动之后需要提取的数据。/sys:
这是linux2.6内核的一个很大的变化。该目录下安装了2.6内核中新出现的一个文件系统 sysfs 。sysfs文件系统集成了下面3种文件系统的信息:针对进程信息的proc文件系统、针对设备的devfs文件系统以及针对伪终端的devpts文件系统。
该文件系统是内核设备树的一个直观反映。
当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。
/tmp:
这个目录是用来存放一些临时文件的。/usr:
这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似与windows下的program files目录。/usr/bin:
系统用户使用的应用程序。/usr/sbin:
超级用户使用的比较高级的管理程序和系统守护程序。/usr/src:内核源代码默认的放置目录。
/var:
这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。
Linux文件基本属性
Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限。为了保护系统的安全性,Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定。
在Linux中我们可以使用 ll 或者 ls –l 命令来显示一个文件的属性以及文件所属的用户和组,如:
[root@www /]# ls -l
total 64
dr-xr-xr-x 2 root root 4096 Dec 14 2012 bin
dr-xr-xr-x 4 root root 4096 Apr 19 2012 boot
……
实例中,bin文件的第一个属性用"d"表示。"d"在Linux中代表该文件是一个目录文件。
在Linux中第一个字符代表这个文件是目录、文件或链接文件等等。
- 当为[ d ]则是目录
- 当为[ - ]则是文件;
- 若是[ l ]则表示为链接文档(link file);
- 若是[ b ]则表示为装置文件里面的可供储存的接口设备(可随机存取装置);
- 若是[ c ]则表示为装置文件里面的串行端口设备,例如键盘、鼠标(一次性读取装置)。
接下来的字符中,以三个为一组,且均为『rwx』 的三个参数的组合。其中,[ r ]代表可读(read)、[ w ]代表可写(write)、[ x ]代表可执行(execute)。 要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号[ - ]而已。
每个文件的属性由左边第一部分的10个字符来确定(如下图)。
从左至右用0-9这些数字来表示。
第0位确定文件类型,第1-3位确定属主(该文件的所有者)拥有该文件的权限。
第4-6位确定属组(所有者的同组用户)拥有该文件的权限,第7-9位确定其他用户拥有该文件的权限。
其中,第1、4、7位表示读权限,如果用"r"字符表示,则有读权限,如果用"-"字符表示,则没有读权限;
第2、5、8位表示写权限,如果用"w"字符表示,则有写权限,如果用"-"字符表示没有写权限;第3、6、9位表示可执行权限,如果用"x"字符表示,则有执行权限,如果用"-"字符表示,则没有执行权限。
Linux文件属主和属组
[root@www /]# ls -l
total 64
dr-xr-xr-x 2 root root 4096 Dec 14 2012 bin
dr-xr-xr-x 4 root root 4096 Apr 19 2012 boot
……
对于文件来说,它都有一个特定的所有者,也就是对该文件具有所有权的用户。
同时,在Linux系统中,用户是按组分类的,一个用户属于一个或多个组。
文件所有者以外的用户又可以分为文件所有者的同组用户和其他用户。
因此,Linux系统按文件所有者
、文件所有者同组用户
和其他用户
来规定了不同的文件访问权限。
在以上实例中,bin文件是一个目录文件,属主和属组都为root,属主有可读、可写、可执行的权限;与属主同组的其他用户有可读和可执行的权限;其他用户也有可读和可执行的权限。
对于 root 用户来说,一般情况下,文件的权限对其不起作用
。
更改文件属性
chgrp
:更改文件属组
chgrp [-R] 属组名 文件名
参数选项
- -R:递归更改文件属组,就是在更改某个目录文件的属组时,如果加上-R的参数,那么该目录下的所有文件的属组都会更改。
chown
:更改文件属主,也可以同时更改文件属组
chown [–R] 属主名 文件名
chown [-R] 属主名:属组名 文件名
进入 /root 目录(~)将install.log的拥有者改为bin这个账号:
[root@www ~] cd ~
[root@www ~]# chown bin install.log
[root@www ~]# ls -l
-rw-r--r-- 1 bin users 68495 Jun 25 08:53 install.log
将install.log的拥有者与群组改回为root:
[root@www ~]# chown root:root install.log
[root@www ~]# ls -l
-rw-r--r-- 1 root root 68495 Jun 25 08:53 install.log
chmod
:更改文件9个属性
chmod [-R] xyz 文件或目录
选项与参数:
- xyz : 就是刚刚提到的数字类型的权限属性,为 rwx 属性数值的相加。
文件的权限字符为:『-rwxrwxrwx』, 这九个权限是三个三个一组的!其中,我们可以使用数字来代表各个权限,各权限的分数对照表如下:
- r:4
- w:2
- x:1
每种身份(owner/group/others)各自的三个权限(r/w/x)分数是需要累加的,例如当权限为: [-rwxrwx---] 分数则是:
- owner = rwx = 4+2+1 = 7
- group = rwx = 4+2+1 = 7
- others= --- = 0+0+0 = 0
所以等一下我们设定权限的变更时,该文件的权限数字就是770
- -R : 进行递归(recursive)的持续变更,亦即连同此目录下的所有文件都会变更
举例来说,如果要将.bashrc这个文件所有的权限都设定启用,那么命令如下:
[root@www ~]# ls -al .bashrc
-rw-r--r-- 1 root root 395 Jul 4 11:45 .bashrc
[root@www ~]# chmod 777 .bashrc
[root@www ~]# ls -al .bashrc
-rwxrwxrwx 1 root root 395 Jul 4 11:45 .bashrc
那如果要将权限变成 -rwxr-xr-- 呢?那么权限的分数就成为 [4+2+1][4+0+1][4+0+0]=754。
九个权限分别是(1)user (2)group (3)others三种身份,那么我们就可以藉由u, g, o来代表三种身份的权限
此外, a 则代表 all 亦即全部的身份!那么读写的权限就可以写成r, w, x!也就是可以使用底下的方式来看:
如果我们需要将文件权限设置为 -rwxr-xr-- ,可以使用 chmod u=rwx,g=rx,o=r 文件名 来设定:
[root@www ~]# ls -al .bashrc -rwxr-xr-x 1 root root 395 Jul 4 11:45 .bashrc [root@www ~]# chmod a+w .bashrc [root@www ~]# ls -al .bashrc -rwxrwxrwx 1 root root 395 Jul 4 11:45 .bashrc
而如果是要将权限去掉而不改变其他已存在的权限呢?例如要拿掉全部人的可执行权限,则:
[root@www ~]# chmod a-x .bashrc [root@www ~]# ls -al .bashrc -rw-rw-rw- 1 root root 395 Jul 4 11:45 .bashrc
Linux文件与目录管理
处理目录常用命令(命令
)
ls
: 列出目录cd
:切换目录pwd
:显示目前的目录mkdir
:创建一个新的目录rmdir
:删除一个空的目录cp
: 复制文件或目录rm
: 移除文件或目录mv
: 移动文件与目录、文件重命名
你可以使用 man [命令] 来查看各个命令的使用文档,如 :man cp。
ls
(列出目录)
在Linux系统当中, ls 命令可能是最常被运行的。
语法:
[root@www ~]# ls [-aAdfFhilnrRSt] 目录名称
[root@www ~]# ls [--color={never,auto,always}] 目录名称
[root@www ~]# ls [--full-time] 目录名称
选项与参数:
-a
:全部的文件,连同隐藏档( 开头为 . 的文件) 一起列出来(常用)-d
:仅列出目录本身,而不是列出目录内的文件数据(常用)-l
:长数据串列出,包含文件的属性与权限等等数据;(常用)
将家目录下的所有文件列出来(含属性与隐藏档)
[root@www ~]# ls -al ~
mkdir
(创建新目录)
如果想要创建新的目录,使用mkdir (make directory)。
mkdir [-mp] 目录名称
选项与参数:
- -m :配置文件的权限,直接配置,不需要管默认权限 (umask)
- -p :帮助你直接将所需要的目录(包含上一级目录)递回创建起来
[root@www ~]# cd /tmp
[root@www tmp]# mkdir test <==创建一名为 test 的新目录
[root@www tmp]# mkdir test1/test2/test3/test4
mkdir: cannot create directory `test1/test2/test3/test4':
No such file or directory <== 没办法直接创建此目录啊!
[root@www tmp]# mkdir -p test1/test2/test3/test4
加了这个 -p 的选项,可以自行帮你创建多层目录
[root@www tmp]# mkdir -m 711 test2
[root@www tmp]# ls -l
drwxr-xr-x 3 root root 4096 Jul 18 12:50 test
drwxr-xr-x 3 root root 4096 Jul 18 12:53 test1
drwx--x--x 2 root root 4096 Jul 18 12:54 test2
上面的权限部分,如果没有加上 -m 来强制配置属性,系统会使用默认属性。
如果我们使用 -m ,如上例我们给予 -m 711
来给予新的目录 drwx--x--x 的权限。
rmdir
(删除空的目录)
语法:
rmdir [-p] 目录名称
选项与参数:
-p
:连同上一级『空的』目录也一起删除
删除 w3cschool.cn 目录
[root@www tmp]# rmdir w3cschool.cn/
[root@www tmp]# ls -l <==看看有多少目录存在?
drwxr-xr-x 3 root root 4096 Jul 18 12:50 test
drwxr-xr-x 3 root root 4096 Jul 18 12:53 test1
drwx--x--x 2 root root 4096 Jul 18 12:54 test2
[root@www tmp]# rmdir test <==可直接删除掉,没问题
[root@www tmp]# rmdir test1 <==因为尚有内容,所以无法删除!
rmdir: `test1': Directory not empty
[root@www tmp]# rmdir -p test1/test2/test3/test4
[root@www tmp]# ls -l <==您看看,底下的输出中test与test1不见了!
drwx--x--x 2 root root 4096 Jul 18 12:54 test2
利用 -p 这个选项,立刻就可以将 test1/test2/test3/test4 一次删除。
不过要注意的是,这个 rmdir 仅能删除空的目录,你可以使用 rm 命令来删除非空目录。
rm
(移除文件或目录)
rm [-fir] 文件或目录
选项与参数:
-f
:就是 force 的意思,忽略不存在的文件,不会出现警告信息;-i
:互动模式,在删除前会询问使用者是否动作-r
:递回删除啊!最常用在目录的删除了!这是非常危险的选项!!!
[root@www tmp]# rm -i bashrc
rm: remove regular file `bashrc'? y
如果加上 -i 的选项就会主动询问喔,避免你删除到错误的档名
cp
(复制文件或目录)
cp 即拷贝文件和目录。
[root@www ~]# cp [-adfilprsu] 来源档(source) 目标档(destination)
[root@www ~]# cp [options] source1 source2 source3 .... directory
-a
:相当于 -pdr 的意思,至於 pdr 请参考下列说明;(常用)-d
:若来源档为连结档的属性(link file),则复制连结档属性而非文件本身;-f
:为强制(force)的意思,若目标文件已经存在且无法开启,则移除后再尝试一次;-i
:若目标档(destination)已经存在时,在覆盖时会先询问动作的进行(常用)-l
:进行硬式连结(hard link)的连结档创建,而非复制文件本身;-p
:连同文件的属性一起复制过去,而非使用默认属性(备份常用);-r
:递回持续复制,用于目录的复制行为;(常用)-s
:复制成为符号连结档 (symbolic link
),亦即『捷径』文件;-u
:若destination
比source
旧才升级 destination !
用root身份,将家目录下的 .bashrc 复制到 /tmp 下,并更名为 bashr
[root@www ~]# cp ~/.bashrc /tmp/bashrc
[root@www ~]# cp -i ~/.bashrc /tmp/bashrc
cp: overwrite `/tmp/bashrc'? n <==n不覆盖,y为覆盖
mv
(移动文件与目录,或修改名称)
[root@www ~]# mv [-fiu] source destination
[root@www ~]# mv [options] source1 source2 source3 .... directory
-f
:force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;-i
:若目标文件 (destination) 已经存在时,就会询问是否覆盖!-u
:若目标文件已经存在,且 source 比较新,才会升级 (update)
复制一文件,创建一目录,将文件移动到目录中
[root@www ~]# cd /tmp
[root@www tmp]# cp ~/.bashrc bashrc
[root@www tmp]# mkdir mvtest
[root@www tmp]# mv bashrc mvtest
将某个文件移动到某个目录去,就是这样做!
将刚刚的目录名称更名为 mvtest2
[root@www tmp]# mv mvtest mvtest2
文件内容查看(命令
)
Linux系统中使用以下命令来查看文件的内容:
cat
由第一行开始显示文件内容tac
从最后一行开始显示,可以看出 tac 是 cat 的倒着写!nl
显示的时候,顺道输出行号!more
一页一页的显示文件内容less
与more
类似,但是比 more 更好的是,他可以往前翻页!head
只看头几行tail
只看尾巴几行
你可以使用 man [命令]来查看各个命令的使用文档,如 :man cp。
cat
由第一行开始显示文件内容
cat [-AbEnTv]
-A
:相当於 -vET 的整合选项,可列出一些特殊字符而不是空白而已;-b
:列出行号,仅针对非空白行做行号显示,空白行不标行号!-E
:将结尾的断行字节 $ 显示出来;-n
:列印出行号,连同空白行也会有行号,与 -b 的选项不同;-T
:将 [tab] 按键以 ^I 显示出来;-v
:列出一些看不出来的特殊字符
检看 /etc/issue 这个文件的内容:
[root@www ~]# cat /etc/issue
CentOS release 6.4 (Final)
Kernel \r on an \m
nl
(显示行号)
nl [-bnw] 文件
选项与参数:
-b
:指定行号指定的方式,主要有两种:-b a
:表示不论是否为空行,也同样列出行号(类似 cat -n);-b t
:如果有空行,空的那一行不要列出行号(默认值);-n
:列出行号表示的方法,主要有三种:-n ln
:行号在萤幕的最左方显示;-n rn
:行号在自己栏位的最右方显示,且不加 0 ;-n rz
:行号在自己栏位的最右方显示,且加 0 ;-w
:行号栏位的占用的位数。
more
(一页一页翻动)
[root@www ~]# more /etc/man.config
#
# Generated automatically from man.conf.in by the
# configure script.
#
# man.conf from man-1.6d
....(中间省略)....
--More--(28%) <== 重点在这一行喔!你的光标也会在这里等待你的命令
在 more 这个程序的运行过程中,你有几个按键可以按的:
空白键 (space)
:代表向下翻一页;Enter
:代表向下翻『一行』;/字串
:代表在这个显示的内容当中,向下搜寻『字串』这个关键字;:f
:立刻显示出档名以及目前显示的行数;q
:代表立刻离开 more ,不再显示该文件内容。b
或[ctrl]-b
:代表往回翻页,不过这动作只对文件有用,对管线无用。
less
(一页一页翻动)
[root@www ~]# less /etc/man.config
#
# Generated automatically from man.conf.in by the
# configure script.
#
# man.conf from man-1.6d
....(中间省略)....
: <== 这里可以等待你输入命令!
less运行时可以输入的命令有:
- 空白键 :向下翻动一页;
- [pagedown]:向下翻动一页;
- [pageup] :向上翻动一页;
- /字串 :向下搜寻『字串』的功能;
- ?字串 :向上搜寻『字串』的功能;
- n :重复前一个搜寻 (与 / 或 ? 有关!)
- N :反向的重复前一个搜寻 (与 / 或 ? 有关!)
- q :离开 less 这个程序;
- less可以按上下方向键来显示上下内容,而more不能通过上下方向键控制显示;
- less不必读整个文件,加载速度比more更快;
- less退出后shell不会留下刚显示的内容,而more退出后会在shell上留下刚显示的内容。
用户和用户组管理
Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统。
用户的账号一方面可以帮助系统管理员对使用系统的用户进行跟踪,并控制他们对系统资源的访问;另一方面也可以帮助用户组织文件,并为用户提供安全性保护。
每个用户账号都拥有一个惟一的用户名和各自的口令。
用户在登录时键入正确的用户名和口令后,就能够进入系统和自己的主目录。
实现用户账号的管理,要完成的工作主要有如下几个方面:
- 用户账号的添加、删除与修改。
- 用户口令的管理。
- 用户组的管理。
用户账号的管理(命令
)
- 添加新的用户账号使用useradd命令,其语法如下:
useradd 选项 用户名
选项:
-c comment
指定一段注释性描述。-d
目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录。-g
用户组 指定用户所属的用户组。-G
用户组,用户组 指定用户所属的附加组。-s
Shell文件 指定用户的登录Shell。-u
用户号 指定用户的用户号,如果同时有-o选项,则可以重复使用其他用户的标识号。
用户名:
指定新账号的登录名。
实例:
useradd –d /usr/xiwen -m xiwen # 新增一个用户xiwen,-d和-m用来为登录名xiwen创建一个主目录/usr/xiwen
# 此命令新建了一个用户xiwen,该用户的登录Shell是 /bin/sh,它属于group用户组,同时又属于adm和root用户组,其中group用户组是其主组
# 这里如果没有组,可能会新建组:#groupadd group及groupadd adm
useradd -s /bin/sh -g group –G adm,root xiwen
- 删除账号
userdel 选项 用户名
常用的选项是-r,它的作用是把用户的主目录一起删除。
- 修改账号
修改已有用户的信息使用usermod
命令
usermod 选项 用户名
常用的选项包括-c, -d, -m, -g, -G, -s, -u以及-o等
,这些选项的意义与useradd
命令中的选项一样,可以为用户指定新的资源值。
另外,有些系统可以使用选项:-l 新用户名
这个选项指定一个新的账号,即将原来的用户名改为新的用户名。
示例:
usermod -s /bin/ksh -d /home/z –g developer xiwen
此命令将用户xiwen的登录Shell修改为ksh,主目录改为/home/z,用户组改为developer。
- 用户口令的管理(密码)
用户账号刚创建时没有口令,但是被系统锁定,无法使用,必须为其指定口令后才可以使用,即使是指定空口令
passwd 选项 用户名
可使用的选项:
-l
锁定口令,即禁用账号-u
口令解锁-d
使账号无口令-f
强迫用户下次登录时修改口令
如果默认用户名,则修改当前用户的口令
如果是超级用户,可以用下列形式指定任何用户的口令:
passwd sam
New password:*******
Re-enter new password:*******
为用户指定空口令时,执行下列形式的命令:
passwd -d sam
passwd命令还可以用-l(lock)
选项锁定某一用户,使其不能登录,例如:
passwd -l sam
用户组的管理(命令
)
每个用户都有一个用户组,系统可以对一个用户组中的所有用户进行集中管理。不同Linux 系统对用户组的规定有所不同,如Linux下的用户属于与它同名的用户组,这个用户组在创建用户时同时创建。
用户组的管理涉及用户组的添加、删除和修改。组的增加、删除和修改实际上就是对/etc/group文件的更新。
- 增加一个新的用户组
使用groupadd
命令,其格式如下
groupadd 选项 用户组
可以使用的选项有:
-g GID
指定新用户组的组标识号(GID)-o
一般与-g选项同时使用,表示新用户组的GID可以与系统已有用户组的GID相同
- 删除一个用户组
groupdel 用户组
- 修改用户组的属性
groupmod 选项 用户组
常用的选项有:
-g GID
为用户组指定新的组标识号。-o
与-g
选项同时使用,用户组的新GID可以与系统已有用户组的GID相同。-n
新用户组 将用户组的名字改为新名字
- 切换用户组
如果一个用户同时属于多个用户组,那么用户可以在用户组之间切换,以便具有其他用户组的权限
newgrp root
这条命令将当前用户切换到root用户组,前提条件是root用户组确实是该用户的主组或附加组。类似于用户账号的管理,用户组的管理也可以通过集成的系统管理工具来完成。
与用户有关的系统文件
完成用户管理的工作有许多种方法,但是每一种方法实际上都是对有关的系统文件进行修改。
与用户和用户组相关的信息都存放在一些系统文件中,这些文件包括/etc/passwd
, /etc/shadow
, /etc/group
等
/etc/passwd
文件
Linux
系统中的每个用户都在/etc/passwd
文件中有一个对应的记录行,它记录了这个用户的一些基本属性
这个文件对所有用户都是可读的
# cat /etc/passwd
root:x:0:0:Superuser:/:
daemon:x:1:1:System daemons:/etc:
bin:x:2:2:Owner of system commands:/bin:
sys:x:3:3:Owner of system files:/usr/sys:
adm:x:4:4:System accounting:/usr/adm:
uucp:x:5:5:UUCP administrator:/usr/lib/uucp:
auth:x:7:21:Authentication administrator:/tcb/files/auth:
cron:x:9:16:Cron daemon:/usr/spool/cron:
listen:x:37:4:Network daemon:/usr/net/nls:
lp:x:71:18:Printer administrator:/usr/spool/lp:
sam:x:200:50:Sam san:/usr/sam:/bin/sh
/etc/passwd
中一行记录对应着一个用户,每行记录又被冒号(:
)分隔为7个字段,其格式和具体含义如下:
用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell
用户标识号
:一般情况下它与用户名是一一对应的。如果几个用户名对应的用户标识号是一样的,系统内部将把它们视为同一个用户,但是它们可以有不同的口令、不同的主目录以及不同的登录Shell等组标识号
:它对应着/etc/group文件中的一条记录注释性描述
:可以用来记录用户的一些信息主目录
:它是用户在登录到系统之后所处的目录。在大多数系统中,各用户的主目录都被组织在同一个特定的目录下,而用户主目录的名称就是该用户的登录名。各用户对自己的主目录有读、写、执行(搜索)权限,其他用户对此目录的访问权限则根据具体情况设置。登录shell
:Shell是用户与Linux系统之间的接口。Linux的Shell有许多种,每种都有不同的特点。常用的有sh(Bourne Shell), csh(C Shell), ksh(Korn Shell), tcsh(TENEX/TOPS-20 type C Shell), bash(Bourne Again Shell)等。
系统管理员可以根据系统情况和用户习惯为用户指定某个Shell。如果不指定Shell,那么系统使用sh为默认的登录Shell,即这个字段的值为/bin/sh。
用户的登录Shell也可以指定为某个特定的程序(此程序不是一个命令解释器)。
利用这一特点,我们可以限制用户只能运行指定的应用程序,在该应用程序运行结束后,用户就自动退出了系统。有些Linux 系统要求只有那些在系统中登记了的程序才能出现在这个字段中。
系统中有一类用户被称为伪用户,这些用户在/etc/passwd文件中也占有一条记录,但是不能登录,因为它们的登录Shell为空。它们的存在主要是方便系统管理,满足相应的系统进程对文件属主的要求
伪 用 户 含 义 bin 拥有可执行的用户命令文件 sys 拥有系统文件 adm 拥有帐户文件 uucp UUCP使用 lp lp或lpd子系统使用 nobody NFS使用
除了上面列出的伪用户外,还有许多标准的伪用户,例如:
audit
,cron
,usenet
等,它们也都各自为相关的进程和文件所需要
/etc/shadow
文件
由于/etc/passwd文件是所有用户都可读的,如果用户的密码太简单或规律比较明显的话,一台普通的计算机就能够很容易地将它破解,因此对安全性要求较高的Linux系统都把加密后的口令字分离出来,单独存放在一个文件中,这个文件是/etc/shadow文件。 有超级用户才拥有该文件读权限,这就保证了用户密码的安全性
/etc/shadow中的记录行与/etc/passwd中的一一对应,它由pwconv命令根据/etc/passwd中的数据自动产生
登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效时间:标志
登录名
是与/etc/passwd文件中的登录名相一致的用户账号口令
字段存放的是加密后的用户口令字,长度为13个字符。如果为空,则对应用户没有口令,登录时不需要口令;如果含有不属于集合 { ./0-9A-Za-z }中的字符,则对应的用户不能登录。最后一次修改时间
表示的是从某个时刻起,到用户最后一次修改口令时的天数。时间起点对不同的系统可能不一样。例如在SCO Linux 中,这个时间起点是1970年1月1日。最小时间间隔
指的是两次修改口令之间所需的最小天数。最大时间间隔
指的是口令保持有效的最大天数。警告时间
字段表示的是从系统开始警告用户到用户密码正式失效之间的天数。不活动时间
表示的是用户没有登录活动但账号仍能保持有效的最大天数。失效时间
字段给出的是一个绝对的天数,如果使用了这个字段,那么就给出相应账号的生存期。期满后,该账号就不再是一个合法的账号,也就不能再用来登录了。
etc/group
文件
将用户分组是Linux 系统中对用户进行管理及控制访问权限的一种手段。
每个用户都属于某个用户组;一个组中可以有多个用户,一个用户也可以属于不同的组。
当一个用户同时是多个组中的成员时,在/etc/passwd文件中记录的是用户所属的主组,也就是登录时所属的默认组,而其他组称为附加组。
用户要访问属于附加组的文件时,必须首先使用newgrp命令使自己成为所要访问的组中的成员。
用户组的所有信息都存放在/etc/group文件中。此文件的格式也类似于/etc/passwd文件,由冒号(:)隔开若干个字段,这些字段有:
组名:口令:组标识号:组内用户列表
组名
是用户组的名称,由字母或数字构成。与/etc/passwd中的登录名一样,组名不应重复。口令
字段存放的是用户组加密后的口令字。一般Linux 系统的用户组都没有口令,即这个字段一般为空,或者是*。组标识号
与用户标识号类似,也是一个整数,被系统内部用来标识组。组内用户列表
是属于这个组的所有用户的列表/b],不同用户之间用逗号(,)分隔。这个用户组可能是用户的主组,也可能是附加组。
root::0:root
bin::2:root,bin
sys::3:root,uucp
adm::4:root,adm
daemon::5:root,daemon
lp::7:root,lp
users::20:root,sam
批量导入用户
添加和删除用户对每位Linux系统管理员都是轻而易举的事,比较棘手的是如果要添加几十个、上百个甚至上千个用户时,我们不太可能还使用useradd一个一个地添加,必然要找一种简便的创建大量用户的方法。Linux系统提供了创建大量用户的工具,可以让您立即创建大量用户,方法如下:
- 先编辑一个文本用户文件
每一列按照/etc/passwd
密码文件的格式书写,要注意每个用户的用户名、UID、宿主目录都不可以相同,其中密码栏可以留做空白或输入x号。一个范例文件user.txt内容如下:
user001::600:100:user:/home/user001:/bin/bash
user002::601:100:user:/home/user002:/bin/bash
user003::602:100:user:/home/user003:/bin/bash
user004::603:100:user:/home/user004:/bin/bash
user005::604:100:user:/home/user005:/bin/bash
user006::605:100:user:/home/user006:/bin/bash
- 以root身份执行命令
/usr/sbin/newusers
,从刚创建的用户文件user.txt
中导入数据,创建用户
newusers < user.txt
然后可以执行命令 vipw
或 vi /etc/passwd
检查 /etc/passwd
文件是否已经出现这些用户的数据,并且用户的宿主目录是否已经创建。
- 执行命令
/usr/sbin/pwunconv
将 /etc/shadow
产生的 shadow
密码解码,然后回写到 /etc/passwd
中,并将/etc/shadow
的shadow
密码栏删掉。这是为了方便下一步的密码转换工作,即先取消 shadow password
功能。
pwunconv
- 编辑每个用户的密码对照文件
范例文件 passwd.txt
内容如下
user001:密码
user002:密码
user003:密码
user004:密码
user005:密码
user006:密码
- 以root身份执行命令
/usr/sbin/chpasswd
创建用户密码,chpasswd
会将经过 /usr/bin/passwd
命令编码过的密码写入 /etc/passwd
的密码栏。
chpasswd < passwd.txt
- 确定密码经编码写入
/etc/passwd
的密码栏后
执行命令 /usr/sbin/pwconv
将密码编码为 shadow password
,并将结果写入 /etc/shadow
。
pwconv
这样就完成了大量用户的创建了,之后您可以到/home下检查这些用户宿主目录的权限设置是否都正确,并登录验证用户密码是否正确。
磁盘管理
Linux磁盘管理好坏管理直接关系到整个系统的性能问题。
Linux磁盘管理常用三个命令为df、du和fdisk。
df
:列出文件系统的整体磁盘使用量du
:检查磁盘空间使用量fdisk
:用于磁盘分区
df
(检查文件系统的磁盘空间占用情况)
df命令参数功能:检查文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息
df [-ahikHTm] [目录或文件名]
选项与参数:
-a
:列出所有的文件系统,包括系统特有的 /proc 等文件系统;-k
:以 KBytes 的容量显示各文件系统;-m
:以 MBytes 的容量显示各文件系统;-h
:以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;-H
:以 M=1000K 取代 M=1024K 的进位方式;-T
:显示文件系统类型, 连同该 partition 的 filesystem 名称 (例如 ext3) 也列出;-i
:不用硬盘容量,而以 inode 的数量来显示
du
(也是查看使用空间的)
Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的,这里介绍Linux du命令
du [-ahskm] 文件或目录名称
-a
:列出所有的文件与目录容量,因为默认仅统计目录底下的文件量而已。-h
:以人们较易读的容量格式 (G/M) 显示;-s
:列出总量而已,而不列出每个各别的目录占用容量;-S
:不包括子目录下的总计,与 -s 有点差别。-k
:以 KBytes 列出容量显示;-m
:以 MBytes 列出容量显示;
fdisk
(磁盘分区表操作工具)
fdisk 是 Linux 的磁盘分区表操作工具
fdisk [-l] 装置名称
-l
:输出后面接的装置所有的分区内容。若仅有 fdisk -l 时, 则系统将会把整个系统内能够搜寻到的装置的分区均列出来。
mkfs
磁盘格式化
磁盘分割完毕后自然就是要进行文件系统的格式化,格式化的命令非常的简单,使用 mkfs
(make filesystem) 命令。
mkfs [-t 文件系统格式] 装置文件名
-t
:可以接文件系统格式,例如 ext3, ext2, vfat 等(系统有支持才会生效)
将分区 /dev/hdc6(可指定你自己的分区) 格式化为 ext3 文件系统:
[root@www ~]# mkfs -t ext3 /dev/hdc6
mke2fs 1.39 (29-May-2006)
Filesystem label= <==这里指的是分割槽的名称(label)
OS type: Linux Block size=4096 (log=2) <==block 的大小配置为 4K
Fragment size=4096 (log=2)
251392 inodes, 502023 blocks <==由此配置决定的inode/block数量
25101 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=515899392
16 block groups 32768 blocks per group,
32768 fragments per group
15712 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912
Writing inode tables: done
Creating journal (8192 blocks): done <==有日志记录
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 34 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
# 这样就创建起来我们所需要的 Ext3 文件系统了!简单明了!
fsck
磁盘
当文件系统被挂载时,操作系统正在读取和写入文件系统中的数据。这意味着文件系统处于活动状态,并且可能存在打开的文件、未完成的写操作等。
潜在的数据损坏: 如果你强行对已挂载的文件系统执行
fsck
,会中断正在进行的文件系统操作,可能导致数据丢失或文件系统结构受损。因此,操作系统强烈建议在文件系统未挂载时才进行fsck
操作,以确保文件系统处于非活动状态。
fsck(file system check)
用来检查和维护不一致的文件系统。
若系统掉电或磁盘发生问题,可利用fsck命令对文件系统进行检查。
fsck [-t 文件系统] [-ACay] 装置名称
-t
: 给定档案系统的型式,若在 /etc/fstab 中已有定义或 kernel 本身已支援的则不需加上此参数-s
: 依序一个一个地执行 fsck 的指令来检查-A
: 对/etc/fstab 中所有列出来的 分区(partition)做检查-C
: 显示完整的检查进度-d
: 打印出 e2fsck 的 debug 结果-p
: 同时有 -A 条件时,同时有多个 fsck 的检查一起执行-R
: 同时有 -A 条件时,省略 / 不检查-V
: 详细显示模式-a
: 如果检查有错则自动修复-r
: 如果检查有错则由使用者回答是否修复-y
: 选项指定检测每个文件是自动输入yes,在不确定那些是不正常的时候,可以执行 # fsck -y 全部检查修复。
强制检测 /dev/hdc6 分区:
[root@www ~]# fsck -C -f -t ext3 /dev/hdc6
fsck 1.39 (29-May-2006)
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
vbird_logical: 11/251968 files (9.1% non-contiguous), 36926/1004046 blocks
如果没有加上 -f 的选项,则由于这个文件系统不曾出现问题,检查的经过非常快速!若加上 -f 强制检查,才会一项一项的显示过程。
mount
(磁盘挂载)和umount
(磁盘卸除)
Linux 的磁盘挂载使用 mount
命令,卸载使用 umount
命令。
- 磁盘挂载语法:
mount [-t 文件系统] [-L Label名] [-o 额外选项] [-n] 装置文件名 挂载点
示例:
#用默认的方式,将刚刚创建的 /dev/hdc6 挂载到 /mnt/hdc6 上面!
[root@www ~]# mkdir /mnt/hdc6
[root@www ~]# mount /dev/hdc6 /mnt/hdc6
[root@www ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
.....中间省略.....
/dev/hdc6 1976312 42072 1833836 3% /mnt/hdc6
- 磁盘卸载语法:
umount [-fn] 装置文件名或挂载点
选项与参数:
-f
:强制卸除!可用在类似网络文件系统 (NFS) 无法读取到的情况下;-n
:不升级 /etc/mtab 情况下卸除。
卸载/dev/hdc6
[root@www ~]# umount /dev/hdc6
磁盘扩容
在fdisk中,先将分区d
指令删除之后,在
磁盘扩容完之后,需要使用sudo resize2fs /dev/sda1
命令进行更新之后,df -h
才能看到扩容成功
Linux
其他命令大全
文件管理
chattr
(更改文件属性)
Linux chattr命令用于改变文件属性。
这项指令可改变存放在ext2文件系统上的文件或目录属性,这些属性共有以下8种模式:
a
:让文件或目录仅供附加用途b
:不更新文件或目录的最后存取时间c
:将文件或目录压缩后存放d
:将文件或目录排除在倾倒操作之外i
:不得任意更动文件或目录s
:保密性删除文件或目录S
:即时更新文件或目录u
:预防以外删除
语法
chattr [-RV][-v<版本编号>][+/-/=<属性>][文件或目录...]
参数
-R
递归处理,将指定目录下的所有文件及子目录一并处理。-v<版本编号>
设置文件或目录版本。-V
显示指令执行过程。+
<属性> 开启文件或目录的该项属性。-
<属性> 关闭文件或目录的该项属性。=
<属性> 指定文件或目录的该项属性
sudo chattr -R -u xiwen #示例
scp
(远程传送文件)
Linux scp命令用于Linux之间复制文件和目录。
scp是 secure copy的缩写, scp是linux系统下基于ssh登陆进行安全的远程文件拷贝命令。
scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program]
[[user@]host1:]file1 [...] [[user@]host2:]file2
简易写法:
scp [可选参数] file_source file_target
参数说明:
-1
: 强制scp命令使用协议ssh1-2
: 强制scp命令使用协议ssh2-4
: 强制scp命令只使用IPv4寻址-6
: 强制scp命令只使用IPv6寻址-B
: 使用批处理模式(传输过程中不询问传输口令或短语)-C
: 允许压缩。(将-C标志传递给ssh,从而打开压缩功能)-p
:保留原文件的修改时间,访问时间和访问权限。-q
: 不显示传输进度条。-r
: 递归复制整个目录。-v
:详细方式显示输出。scp和ssh(1)会显示出整个过程的调试信息。这些信息用于调试连接,验证和配置问题。-c cipher
: 以cipher将数据传输进行加密,这个选项将直接传递给ssh。-F ssh_config
: 指定一个替代的ssh配置文件,此参数直接传递给ssh。-i identity_file
: 从指定文件中读取传输时使用的密钥文件,此参数直接传递给ssh。-l limit
: 限定用户所能使用的带宽,以Kbit/s为单位。-o ssh_option
: 如果习惯于使用ssh_config(5)中的参数传递方式,-P port
:注意是大写的P, port是指定数据传输用到的端口号-S program
: 指定加密传输时所使用的程序。此程序必须能够理解ssh(1)的选项。
从本地复制到远程
scp local_file remote_username@remote_ip:remote_folder
# 或者
scp local_file remote_username@remote_ip:remote_file
# 或者
scp local_file remote_ip:remote_folder
# 或者
scp local_file remote_ip:remote_file
示例:
scp /home/space/music/1.mp3 root@www.w3cschool.cn:/home/root/others/music
scp /home/space/music/1.mp3 root@www.w3cschool.cn:/home/root/others/music/001.mp3
scp /home/space/music/1.mp3 www.w3cschool.cn:/home/root/others/music
scp /home/space/music/1.mp3 www.w3cschool.cn:/home/root/others/music/001.mp3
复制目录命令格式:
scp -r local_folder remote_username@remote_ip:remote_folder
# 或者
scp -r local_folder remote_ip:remote_folder
- 第1个指定了用户名,命令执行后需要再输入密码;
- 第2个没有指定用户名,命令执行后需要输入用户名和密码;
从远程复制到本地
从远程复制到本地,只要将从本地复制到远程的命令的后2个参数调换顺序即可,如下实例
scp root@www.w3cschool.cn:/home/root/others/music /home/space/music/1.mp3
scp -r www.w3cschool.cn:/home/root/others/ /home/space/music/
如果远程服务器防火墙有为scp命令设置了指定的端口,我们需要使用 -p 参数来设置命令的端口号,命令格式如下:
#scp命令使用端口号 4588 scp -p 4588 remote@www.w3cschool.cn:/usr/local/sin.sh /home/administrator
使用scp命令要确保使用的用户具有可读取远程服务器相应文件的权限,否则scp命令是无法起作用的。
备份压缩
tar
(压缩解压tar.gz后缀)
tar [-ABcdgGhiklmMoOpPrRsStuUvwWxzZ][-b <区块数目>][-C <目的目录>][-f <备份文件>][-F <Script文件>][-K <文件>][-L <媒体容量>][-N <日期时间>][-T <范本文件>][-V <卷册名称>][-X <范本文件>][-<设备编号><存储密度>][--after-date=<日期时间>][--atime-preserve][--backuup=<备份方式>][--checkpoint][--concatenate][--confirmation][--delete][--exclude=<范本样式>][--force-local][--group=<群组名称>][--help][--ignore-failed-read][--new-volume-script=<Script文件>][--newer-mtime][--no-recursion][--null][--numeric-owner][--owner=<用户名称>][--posix][--erve][--preserve-order][--preserve-permissions][--record-size=<区块数目>][--recursive-unlink][--remove-files][--rsh-command=<执行指令>][--same-owner][--suffix=<备份字尾字符串>][--totals][--use-compress-program=<执行指令>][--version][--volno-file=<编号文件>][文件或目录...]
参数:
-c
或--create
建立新的备份文件(压缩文件)-x
或--extract
或--get
从备份文件中还原文件(解压文件)-z
或--gzip
或--ungzip
通过gzip指令处理备份文件(如果要压缩成tar.gz)-v
或--verbose
显示指令执行过程-f<备份文件>
或--file=<备份文件>
指定备份文件-t
或--list
列出备份文件的内容。
压缩文件:
tar -cvf myarchive.tar file1.txt file2.txt directory
# 这将创建一个名为 .tar 的归档文件,包含 file1.txt, file2.txt 和 directory。
# 要创建一个 .tar.gz 格式的压缩文件,可以将 gzip 与 tar 命令结合使用:
tar -czvf archive.tar.gz file1 file2 ...
解压文件:
#.tar
tar -xvf archive.tar
#.tar.gz
tar -xzvf archive.tar.gz
#解压到指定文件下:
tar [-xvf/-xzvf] archive.[tar/tar.gz] -C /home/destination
查看归档文件
tar -tvf archive.[tar/tar.gz]
zip
zip
zip [-AcdDfFghjJKlLmoqrSTuvVwXyz$][-b <工作目录>][-ll][-n <字尾字符串>][-t <日期时间>][-<压缩效率>][压缩文件][文件...][-i <范本样式>][-x <范本样式>]
-A
调整可执行的自动解压缩文件。-b<工作目录>
指定暂时存放文件的目录。-c
替每个被压缩的文件加上注释。-d
从压缩文件内删除指定的文件-D
压缩文件内不建立目录名称。-f
此参数的效果和指定"-u"参数类似,但不仅更新既有文件,如果某些文件原本不存在于压缩文件内,使用本参数会一并将其加入压缩文件中。-F
尝试修复已损坏的压缩文件。-g
将文件压缩后附加在既有的压缩文件之后,而非另行建立新的压缩文件。-h
在线帮助。-i<范本样式>
只压缩符合条件的文件。-j
只保存文件名称及其内容,而不存放任何目录名称。-J
删除压缩文件前面不必要的数据。-k
使用MS-DOS兼容格式的文件名称。-l
压缩文件时,把LF字符置换成LF+CR字符。-ll
压缩文件时,把LF+CR字符置换成LF字符。-L
显示版权信息。-m
将文件压缩并加入压缩文件后,删除原始文件,即把文件移到压缩文件中。-n<字尾字符串>
不压缩具有特定字尾字符串的文件。-o
以压缩文件内拥有最新更改时间的文件为准,将压缩文件的更改时间设成和该文件相同。-q
不显示指令执行过程。-r
递归处理,将指定目录下的所有文件和子目录一并处理-S
包含系统和隐藏文件。-t
<日期时间> 把压缩文件的日期设成指定的日期。-T
检查备份文件内的每个文件是否正确无误。-u
更换较新的文件到压缩文件内。-v
显示指令执行过程或显示版本信息-V
保存VMS操作系统的文件属性。-w
在文件名称里假如版本编号,本参数仅在VMS操作系统下有效。-x<范本样式>
压缩时排除符合条件的文件。-X
不保存额外的文件属性。-y
直接保存符号连接,而非该连接所指向的文件,本参数仅在UNIX之类的系统下有效。-z
替压缩文件加上注释。-$
保存第一个被压缩文件所在磁盘的卷册名称。-<压缩效率>
压缩效率是一个介于1-9的数值。
示例:
zip -rv ok.zip ./*
unzip
unzip [-cflptuvz][-agCjLMnoqsVX][-P <密码>][.zip文件][文件][-d <目录>][-x <文件>] 或 unzip [-Z]
-c
将解压缩的结果显示到屏幕上,并对字符做适当的转换。-f
更新现有的文件。-l
显示压缩文件内所包含的文件。-p
与-c
参数类似,会将解压缩的结果显示到屏幕上,但不会执行任何的转换。-t
检查压缩文件是否正确。-u
与-f
参数类似,但是除了更新现有的文件外,也会将压缩文件中的其他文件解压缩到目录中。-v
执行是时显示详细的信息。-z
仅显示压缩文件的备注文字。-a
对文本文件进行必要的字符转换。-b
不要对文本文件进行字符转换。-C
压缩文件中的文件名称区分大小写。-j
不处理压缩文件中原有的目录路径。-L
将压缩文件中的全部文件名改为小写。-M
将输出结果送到more程序处理。-n
解压缩时不要覆盖原有的文件。-o
不必先询问用户,unzip执行后覆盖原有文件。-P
<密码> 使用zip的密码选项。-q
执行时不显示任何信息。-s
将文件名中的空白字符转换为底线字符。-V
保留VMS的文件版本信息。-X
解压缩时同时回存文件原来的UID/GID。- [.zip文件] 指定.zip压缩文件。
- [文件] 指定要处理.zip压缩文件中的哪些文件。
-d<目录>
指定文件解压缩后所要存储的目录。-x<文件>
指定不要处理.zip压缩文件中的哪些文件。-Z unzip -Z
等于执行zipinfo指令。
示例:
unzip xxx.zip -d ./destination
zipinfo
zipinfo [-12hlmMstTvz][压缩文件][文件...][-x <范本样式>]
-1
只列出文件名称。-2
此参数的效果和指定"-1"参数类似,但可搭配"-h","-t"和"-z"参数使用。-h
只列出压缩文件的文件名称。-l
此参数的效果和指定"-m"参数类似,但会列出原始文件的大小而非每个文件的压缩率。-m
此参数的效果和指定"-s"参数类似,但多会列出每个文件的压缩率。-M
若信息内容超过一个画面,则采用类似more指令的方式列出信息。-s
用类似执行"ls -l"指令的效果列出压缩文件内容。-t
只列出压缩文件内所包含的文件数目,压缩前后的文件大小及压缩率。-T
将压缩文件内每个文件的日期时间用年,月,日,时,分,秒的顺序列出。-v
详细显示压缩文件内每一个文件的信息。-x<范本样式>
不列出符合条件的文件的信息。-z
如果压缩文件内含有注释,就将注释显示出来。
zipinfo -2htz ok.zip
shell
语法
hello world
#!/bin/bash
echo "Hello World !"
"#!" 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
echo 命令用于向窗口输出文本。
运行 Shell 脚本有两种方法:
- 作为可执行程序
将上面的代码保存为 test.sh,并 cd 到相应目录:
chmod +x ./test.sh #使脚本具有执行权限
./test.sh #执行脚本
注意,一定要写成 ./test.sh ,而不是 test.sh ,运行其它二进制的程序也一样,直接写 test.sh ,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。
- 作为解释器参数
这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:
/bin/sh test.sh
/bin/php test.php
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。
shell变量
定义变量时,变量名不加美元符号($,PHP语言中变量需要),如:
your_name="w3cschool.cn"
注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
- 首个字符必须为字母(a-z,A-Z)。
- 中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
- 不能使用bash里的关键字(可用help命令查看保留关键字)。
除了显式地直接赋值,还可以用语句给变量赋值,如:
for file in `ls /etc`
以上语句将 /etc 下目录的文件名循环出来。
使用变量
使用一个定义过的变量,只要在变量名前面加美元符号即可,如:
your_name="qinjx"
echo $your_name
echo ${your_name}
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
for skill in Ada Coffe Action Java ; do
echo "I am good at ${skill}Script"
done
shell字符串
字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。单双引号的区别跟PHP类似。
单引号
str='this is a string'
单引号字符串的限制:
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
双引号
your_name='qinjx'
str="Hello, I know your are \"$your_name\"! \n"
双引号的优点:
- 双引号里可以有变量
- 双引号里可以出现转义字符
拼接字符串
your_name="qinjx"
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
获取字符串长度
string="abcd"
echo ${#string} #输出 4
提取子字符串
string="alibaba is a great company"
echo ${string:1:4} #输出liba
查找子字符串
string="alibaba is a great company"
echo `expr index "$string" is`
注意: 以上脚本中 "`" 是反引号,而不是单引号 "'",不要看错了哦。
shell数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。
定义数组
在Shell中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
数组名=(值1 值2 ... 值n)
例如:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
还可以单独定义数组的各个分量:
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
可以不使用连续的下标,而且下标的范围没有限制。
读取数组
读取数组元素值的一般格式是:
${数组名[下标]}
例如:
valuen=${array_name[n]}
使用@符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}
获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
shell传递参数
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
实例
以下实例我们向脚本传递三个参数,并分别输出,其中 $0 为执行的文件名:
#!/bin/bash
# author:W3Cschool教程
# url:www.w3cschool.cn
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
为脚本设置可执行权限,并执行脚本,输出结果如下所示:
$ chmod +x test.sh
$ ./test.sh 1 2 3
Shell 传递参数实例!
执行的文件名:test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
另外,还有几个特殊字符用来处理参数:
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与\(*相同,但是使用时加引号,并在引号中返回每个参数。 如"\)@"用「"」括起来的情况、以"$1" "\(2" … "\)n" 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
#!/bin/bash
# author:W3Cschool教程
# url:www.w3cschool.cn
echo "Shell 传递参数实例!";
echo "第一个参数为:$1";
echo "参数个数为:$#";
echo "传递的参数作为一个字符串显示:$*";
执行脚本,输出结果如下所示:
$ chmod +x test.sh
$ ./test.sh 1 2 3
Shell 传递参数实例!
第一个参数为:1
参数个数为:3
传递的参数作为一个字符串显示:1 2 3
$* 与 $@ 区别:
- 相同点:都是引用所有参数。
- 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。
#!/bin/bash
# author:W3Cschool教程
# url:www.w3cschool.cn
echo "-- \$* 演示 ---"
for i in "$*"; do
echo $i
done
echo "-- \$@ 演示 ---"
for i in "$@"; do
echo $i
done
执行脚本,输出结果如下所示:
$ chmod +x test.sh
$ ./test.sh 1 2 3
-- $* 演示 ---
1 2 3
-- $@ 演示 ---
1
2
3
shell运算符
Shell 和其他编程语言一样,支持多种运算符,包括:
- 算数运算符
- 关系运算符
- 布尔运算符
- 字符串运算符
- 文件测试运算符
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
例如,两个数相加(注意使用的是反引号 ` 而不是单引号 '):
#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val"
执行脚本,输出结果如下所示:
两数之和为 : 4
两点注意:
- 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
- 完整的表达式要被 `` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。
算术运算符
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true |
布尔运算符
下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
逻辑运算符
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 |
字符串运算符
下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true。 | [ -n $a ] 返回 true。 |
str | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。
属性检测描述如下:
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
Shell流程控制
if
else
if
if condition
then
command1
command2
...
commandN
fi
写成一行(适用于终端命令提示符):
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
末尾的fi就是if倒过来拼写,后面还会遇到类似的。
if else
if condition
then
command1
command2
...
commandN
else
command
fi
if else-if else
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
if else语句经常与test命令结合使用,如下所示:
num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
echo '两个数字相等!'
else
echo '两个数字不相等!'
fi
for
循环
与其他编程语言类似,Shell支持for循环
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
写成一行:
for var in item1 item2 ... itemN; do command1; command2… done;
当变量值在列表里,for循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的shell命令和语句。in列表可以包含替换、字符串和文件名。
in列表是可选的,如果不用它,for循环使用命令行的位置参数。
例如,顺序输出当前列表中的数字:
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
输出结果:
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
顺序输出字符串中的字符:
for str in 'This is a string'
do
echo $str
done
输出结果:
This is a string
while
语句
while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:
while condition
do
command
done
以下是一个基本的while循环,测试条件是:如果int小于等于5,那么条件返回真。int从0开始,每次循环处理时,int加1。运行上述脚本,返回数字1到5,然后终止。
#!/bin/sh
int=1
while(( $int<=5 )) do echo $int let "int++" done
运行脚本,输出:
1
2
3
4
5
while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按
echo '按下 <CTRL-D> 退出'
echo -n '输入你最喜欢的电影名: '
while read FILM
do
echo "是的!$FILM 是一部好电影"
done
运行脚本,输出类似下面:
按下 <CTRL-D> 退出
输入你最喜欢的电影名: W3Cschool在线教程
是的!W3Cschool在线教程 是一部好电影
无限循环
无限循环语法格式:
while :
do
command
done
或者
while true
do
command
done
或者
for (( ; ; ))
跳出循环
break
命令
break命令允许跳出所有循环(终止执行后面的所有循环)。
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done
执行以上代码,输出结果为:
输入 1 到 5 之间的数字:3
你输入的数字为 3!
输入 1 到 5 之间的数字:7
你输入的数字不是 1 到 5 之间的! 游戏结束
continue
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字: "
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
continue
echo "游戏结束"
;;
esac
done