ubuntu学习笔记之一

1.gksu与sudo指令

gksu用来执行图形的(GUI)程序 GUI = Graphical User Interface

sudo用来执行命令行(CLI)程序 CLI = Command Line Interface

su/sudo for CLI commands, and gksu/gksudo for running GUI applications (launched from the command line).

In ubuntu gksudo is just a link to gksu, so your always running gksu anyways. You can check for yourself> nautilus /usr/bin

Here's a little known tip, if you run just "gksu" you will get a root run dialog, to run any app as root or other user.


gksu and gksudo are in the graphical environments what su and sudo are in the terminal.

By the way, I have read in another thread: people should use gksudo in the terminal to launch a graphical application with root privileges; for example "gksudo gedit". It is also possible to use "sudo gedit", but it is not a good way to do it, because gksudo sets up things for a graphical environment, but sudo sets them up for a text environment. (or something like this)


2.历史命令history

当我们以 bash 登入 Linux 主机之后, 系统会主动的由家目录的 ~/.bash_history 读取以前曾经下过的指令, 至于 ~/.bash_history 会记录多少笔记录则与 bash 的 HISTFILESIZE 这个变量设定值有关

!number(执行该历史命令)


3.man指令

代号                                       代表内容

1         用户在 shell 环境中可以操作的指令或可执行文件

5         配置文件或者是某些档案的格式

8         系统管理员可用的管理指令


4.观察系统的状态

如果要看目前有谁在线,可以下达 who 指令,而如果要看网络的联机状态,可以下达 netstat -a 这个指令,而要看背景执行的程序可以执行 ps -aux 这个指令。

使用这些指令可以让你稍微了解主机目前使用的状态。由 finger account 可以取得该账号的相关说明内容, dmesg 可列出核心产生的信息.


5.正确的关机指令使用

将数据同步写入硬盘的指令:sync

惯用的关机指令:shutdown

sudo shutdown -h now(立刻关机) sudo shutdown -r  (立刻重启)

重新启动, 关机:reboot, halt, poweroff


6.基本上,依据有无网络和 X Window 而将 run level 分为7个等级,分别是:

0    halt(系统直接关机)

1    single user model (单人维护模式,用在系统出问题时的维护)

2    Multi-user, without NFS (类似底下的 runlevel 3, 但无NFS服务)

3    Full multi-user model (完整含有网络功能的纯文本模式)

4    unused (系统保留功能)

5    X11 (与 runlevel 3 类似,但加载使用 X Window)

6    reboot (重新启动)


7.文件属性与权限

chgrp    改变档案所属群组(要被改变的组名必须要在/etc/group档案内存在才行,否则会显示错误)

chown  改变档案拥有者(用户必须要是已经存在系统中的账号,也就是在/etc/passwd这个档案中有记录的用户名才能改变)

chmod  改变档案的权限,SUID, SGID, SBIT等等的特性


8.在Windows底下一个档案是否具有执行的能力是藉由【扩展名】来判断的,例如 .exe, .bat, .com 等等,但是在Linux底下,我们的档案是否能被执行,则是藉由是否具有【x】这个权限来决定的,与档案名没有绝对的关系。不过,可以被执行跟可以执行成功是不一样的,x 代表档案具有可执行的能力,但是能不能执行成功,还要看该档案的内容。

    虽然如此,我们还是希望可以藉由扩展名来了解该档案是什么东西,所以,通常我们还是会以适当的扩展名来表示该档案是什么种类的。例如 .sh, .tar, .tar.tz, .html 等等,总之,Linux系统上的文件名只是让你了解该档案可能的用途而已,真正的执行与否仍然需要权限的规范才行。


9.FHS(Filesystem Hierarchy Standard) 针对目录树架构定义出三层目录底下应该放置什么数据,分别是:

/ (root, 根目录) : 与开机系统有关

/usr (unix software resourse) : 与软件安装/执行有关

/var (variable) : 与系统运作过程有关


    因为根目录与开机有关,开机过程中仅有根目录会被挂载,其他分割槽则是在开机完成后才会持续的进行挂载的行为,因此,根目录下与开机过程有关的目录就不能和根目录放到不同的分割槽去。包括底下这些:

/etc : 配置文件

/bin : 重要执行档

/dev : 所需要的装置档案

/lib : 执行档所需的函式库与核心所需的模块

/sbin 重要的系统执行文件


10.实体链接 (hard link), 或称硬式链接,简单的说就是在某个 目录下新增一笔档名链接到某 inode 号码的关联记录而已,这两个档名链接到同一个 inode ,自然这两个文件名的所有相关信息都会一模一样(除了文件名外)。如果将其中任何一个 [档名] 删除。其实 inode 和 block 还是存在的,此时可以通过另一个 [档名] 来读取到正确的档案数据。

    hard link 的限制: 不能跨 filesystem; 不能 link 目录. 这是因为如果使用 hard link 链接到目录, 链接的数据需要连同被链接目录底下的所以数据都建立链接等.

     符号链接(symbol link), 简单的说即为一个快捷方式。基本上,symbolic link 就是在建立一个独立的档案,而这个档案会让数据的读取指向他 link 的那个档案的档名,由于只是利用档案来作为指向的动作,所以,档来源档被删除之后, symbolic link 的档案会打不开,实际上就是找不到原始 [档名] 而已。

    由上面的说明来看, 似乎 hard link 比较安全, 因为即使一个目录下的关联数据被删掉了, 也没有关系, 只要有任何一个目录下存在着关联数据, 那么该档案就不会不见. 不过由于 hard link 的限制太多, 包括无法做到目录的 link, 所以在用途上还是比较受限制的, 反而是 symbolic link 的使用方面较广.


11.tail -f : 表示持续侦测后面所接的档名,要等到 Ctrl^C 才会结束 tail 的侦测.


12.每个档案在 linux 下都会记录许多的时间参数, 其实是有三个主要的变动时间:

modification time (mtime) : 当该档案的 [内容数据] 变更时, 就会更新这个时间. 内容数据指的是档案的内容, 而不是档案的属性或权限

status time (ctime) : 当该档案的 [状态(status)] 改变时, 就会更新这个时间. 举例来说, 像是权限与属性被更改了, 都会更新这个时间

access time (atime) : 当 [该档案的内容被取用] 时, 就会更新这个读取时间(access). 举例来说, 我们使用 cat 去读取 /etc/man.config, 就会更新该档案的 atime

    在默认的情况下, ls 显示出来的是该档案的 mtime, 也就是这个档案的内容上次被更动的时间. 档案的时间是很重要的, 因为, 如果档案的时间误判的话, 可能会造成某些程序无法顺利的执行.


13.除了普通权限 rwx 外, 还有其他的特殊权限 (s 和 t).

    当 s 这个标志出现在档案拥有者的 x 权限上时, 例如 /usr/bin/passwd 这个档案的权限状态 [-rwsr-xr-x], 此时就被成为 Set UID, 简称为 SUID 的特殊权限. 基本上 SUID 有这样的限制与功能: SUID 权限仅对二进制程序(binary program) 有效; 执行者对于该程序需要具有 x 的可执行权限; 本权限仅在执行该程序的过程中有效 (run-time); 执行者将具有程序拥有者 (owner) 的权限. 举例来说, Linux 系统中, 所有账号的密码都记录在 /etc/shadow 这个档案里, 这个档案的权限为 [-r-------- 1 root root], 意思是这个档案仅有 root 可读且仅有 root 可强制写入, 但一般用户却可以修改自己的密码, 因为一般用户对该档案就要 x 的权限, 在执行过程中 [暂时] 获得 root 的权限,这就是 SUID 的功能.

    当 s 这个标志出现在群组的 x 时则称为 Set GID, SGID. 与 SUID 不同的是, SGID 可以针对档案或目录来设定, 如果是对档案来说, SGID 有如下的功能: SGID 对二进制程序有效; 程序执行者对程序来说, 需具备 x 的权限; 执行者在执行过程中将会获得该程序群组的支持. 举例来说, /usr/bin/locate 这个程序可以去搜寻 /var/lib/mlocate/mlocate.db 这个档案的内容, 上诉两个档案的权限分别为 [-rwx--s--x 1 root slocate] 和 [-rw-r----- 1 root slocate], 若使用一般用户去执行 locate 时, 那该用户会取得 slocate 群组的支持, 因此就能够读取mlocate.db.

    除了 binary program 外, 事实上 SGID 也能够用在目录上,  这也是非常常见的一种用途. 当一个目录设定了 SGID 的权限后, 他将具有如下的功能: 用户若对此目录具有 r 与 x 权限时, 该用户能够进入此目录; 用户在此目录下的有效群组(effective group)将会变成该目录的群组; 用途: 若用户在此目录下具有 w 的权限(可以新建档案), 则使用者所建立的新档案的群组与此目录的群组相同.


    Sticky Bit, SBIT 目前只针对目录有效, 对于档案已经没有效果了. SBIT 对目录的作用是: 当用户对于此目录具有 w, x 权限, 亦即具有写入的权限时, 则当用户在该目录下建立档案或目录时, 仅有自己与 root 才有权力删除该档案. 换句话说: 当甲这个用户对于 A 目录是具有群组或其他人的身份, 并且拥有该目录 w 的权限, 这表示 [甲用户对目录内任何人建立的目录或档案均可进行 "删除/更名/搬移" 等动作]. 不过, 如果将 A 目录加上 SBIT 的权限项目时, 则甲只能够针对自己建立的档案或目录进行上诉动作. 举例来说, /tmp 本身的权限是 [drwxrwxrwt], 在这样的权限下内容下, 任何人都可以在 /tmp 内新增/修改档案, 但仅有该档案/目录建立者与 root 能够删除自己的目录或档案.


14.find 是很强大的搜寻指令, 但时间话费很大, (因为他是直接搜寻硬盘). 这个时候 whereis 和 locate 就显得相当好用了, 这是因为 Linux 系统会将系统内的所有档案都记录在一个数据库档案里, 而当使用 whereis 或者是 locate 时, 都会以次数据库档案的内容为准, 因此, 有的时候会发现使用这两个执行档时, 会找到已经被杀掉的档案, 而且也找不到最新的刚刚建立的档案, 这是因为这两个指令是由数据库当中的结果去搜寻档案的所在.(手动更新 locate 数据库的指令 [updatedb])

    如果你要找的档案是具有特殊属性的, 例如 SUID. 档案拥有者, 档案大小等, 那么利用 locate 是没有办法达成你的搜寻要求的, 此时 find 就显得很重要


15.每个 filesystem 都有独立的 inode/ block / superblock 等信息, 这个文件系统要能够链接到目录才能被我们使用. 将文件系统与目录树结合的动作成为 [挂载]. 所谓的挂载就是利用一个目录当成一个进入点, 将磁盘分割槽的数据放置在该目录下, 进入该目录就可以读取该分割槽. 举例来说, 假设硬盘分为两槽, partition1 是挂载到根目录, 至于 partition2 则是挂载到 /home 这个目录. 这意味着, 当数据放置在 /home 内的各次目录时, 数据是放置到 partition2的, 如果不是放在 /home 底下的目录, 那么数据就会被放置到 partition1.

    而要判断某个档案在哪个 partition 底下是很简单的. 透过反向追踪即可. 以上例来说, 当我想知道 /home/test 这个档案在哪个 partition 时, 由 test --> home --> /, 看那个 [进入点] 先被查到那就是使用的进入点. 所以 test 使用的是 /home 这个进入点而不是 /.


16.进行挂载前, 最好先确定:

单一文件系统不应该重复挂载在不同的挂载点(目录)中;

单一目录不应该重复挂载多个文件系统;

要作为挂载点的目录, 理论上都应该是空目录才是.

    如果要用来挂载的目录不是空的, 那么挂载了文件系统之后, 原目录下的东西就会暂时消失. 举例来说, 假设你的 /home 原本与根目录在同一个和文件系统中, 底下原本有 /home/test1 与 /home/test2 两个目录, 然后你想要加入新的硬盘, 并且直接挂载 /home 底下, 那么当你挂载上新的分割槽时,  则 /home 目录显示的是新分割槽内的资料, 至于原先的 test1 与 test2 这两个目录就会暂时的被隐藏掉了. 注意, 并不是被覆盖掉, 而是暂时的被隐藏了起来, 等到新的分割槽被卸除后, 则 /home 原本的内容就会再次跑出来.


17.几种常见文件系统类型:

ext2/ext3 : Linux 适用的文件系统类型. ext3 文件系统多了日志的记录, 对于系统的复原比较快速.

physical volume(LVM) : 这是用来弹性调整文件系统容量的一种机制, 可以让你的文件系统容量变大或变小而不改变原有的档案数据内容.

software RAID : 利用 Linux 操作系统的特性, 用软件仿真出磁盘阵列的功能.

swap : 就是内存置换空间, swap 并不会使用到目录树的挂载, 所以用 swap 不需要指定挂载点.

vfat : 同时被 Linux 与 Windows 所支持的文件系统类型. 如果你的主机硬盘同时存在 Linux 与 Windows 操作系统, 为了数据的交换, 可以建立一个 vfat 的文件系统.


18.几个常见的压缩文件扩展名:

*.Z : compress 程序压缩的档案

*.gz : gzip 程序压缩的档案

*.bz2 : bzip2 程序压缩的档案

*.tar : tar 程序打包的数据, 并没有压缩过

*.tar.gz : tar 程序打包的档案, 并且经过 gzip 的压缩

*.tar.bz2 : tar 程序打包的档案, 并且经过 bzip2 的压缩

    最简单的使用 tar 就只要记得底下的方式即可:

压    缩 ; tar -jcv -f filename.tar.bz2 要被压缩的档案或目录名称

查    询 : tar -jtv -f filename.tar.bz2

解压缩 : tar -jxv -f filename.tar.bz2 -C 欲解压缩的目录

    那个 filename.tar.bz2 是我们自己取的档案名, tar 并不会主动产生建立的档案名. 如果不加 [-j|-z] 的话, 档案名最好取 *.tar 即可, 如果是 -j 选项, 代表有 bzip2 的支持, 所以档案名最好取为 *.tar.bz2, 因为 bzip2 会产生 .bz2 的扩展名. 至于如果是加上了 -z 的 gzip 的支持, 那档名最好取为 *.tar.gz.

    另外, 由于 [-f filename] 是紧接在一起的, 常常写成 [tar -jcvf filename], 这样写是对的, 但由于选项的顺序理论上是可以变换的, 所以若误认为 [tar -jvfc filename] 也可以. 而事实上,这样会导致产生的档名变成 c, 因为 -fc... 所以, 建议在学习使用 tar 时, 将 [-f filename] 与其他选项独立出来会比较好.

    打包备份档案时会拿掉根目录, 主要是为了安全. 使用 tar 备份的数据可能会需要解压缩回来使用, 在 tar 所记录的文件名就是解压缩后的实际档案名. 如果拿掉了根目录, 假设你将备份数据在 /tmp 解开, 那么解压缩后的档案名就会变成 /tmp/xxx,.但如果没有拿掉根目录, 解压缩后的档案名就是绝对路径, 亦即解压缩后的数据一定会被放置到 /xxx, 如此一来, 原本的数据就会被备份数据覆盖.


19. DOS 与 Linux 的断行字符

    利用 cat -A 来观察以 DOS(Windows 系统)建立的档案的特殊格式, 可以发现 DOS 使用的断行字符为 ^M$, 我们称之为 CR 和 LF 两个符号. 而在 Linux 底下, 则是仅有 LF($) 这个断行符号.

    在 Linux 底下的指令在开始执行时, 他的判断依据是 Enter, 而 Linux 的 Enter 为 LF 符号, 不过, 由于 DOS 的断行符号是 CRLF, 也就是多出了一个 ^M 的符号出来, 在这样的情况下, 如果是一个 shell script 的程序档案, 将可能造成 [程序无法运行] 的状态, 因为他会误判程序所下达的指令内容.


20. 只要是能够操作应用程序的接口都能够称为壳程序. 狭义的壳程序指的是指令列方面的软件, 包括 bash(Bourne Again Shell) 等. 广义的壳程序则包括图形接口的软件. 因为图形接口其实也能够操作各种应用程序来呼出核心工作. 可以使用的 shells 例如:

/bin/sh    (已经被 bash 所取代)

/bin/bash    (就是 Linux 预设的 shell)等

系统上合法的 shell 要写入 /etc/shells 这个档案, 是因为系统某些服务在运行过程中, 会去检查使用者能够使用的 shells, 而这些 shells 的查询就是藉由 /etc/shells 这个档案.而且当我登入的时候, 系统就会给我一个 shell 让我来工作. 而这个登入取得的 shell 就记录在 /etc/passwd 这个档案内.


bash 的主要优点有:

1) 命令修编能力(history) : 可以查询曾经做过的动作

2) 命令与档案补全功能([ab键的好处) : Tab 接在一串指令的第一个字后面, 则为命令补全; Tab 接在一串指令的第二个字以后时, 则为档案补全

3) 命令别名设定功能(alias)

4) 工作控制及前景背景控制(job control, foreground, background)

5) 程序化脚本(shell scripts)

6) 通配符(Wildcard)


21. 目前大多数的 distributions 都会有随机数生成器, 就是 /dev/random 这个档案. 在 BASH 的环境下, 这个 RANDOM 变量的内容, 介于 0~32767 之间.

declare -i number=$RANDOM*10/32768;echo $number
#此时会随机取出 0~9之间的数值


22. PS1 就是我们的命令提示符, 每当我们按下 Enter 按键去执行某个指令后, 最后要再次出现提示字符时, 就会主动去读取这个变量值. 每个 distribution 的 bash 默认的 PS1 变量内容可能有些许的差异, 但可以按自己的习惯设定.

\d : 可显示处 [星期 月 日] 的日期格式, 如 "Mon Feb 2"
\H : 完整的主机名,如 [www.xxx.yyy]
\h : 仅去主机名在第一个小数点之前的名字, 则应为 [www]

\t : 显示时间, 为 24 小时格式的 [HH:MM:SS]
\T : 显示时间, 为 12 小时格式的 [HH:MM:SS]
\A : 显示时间,为 12 小时格式的 [HH:MM]
\@ : 显示时间, 为12 小时格式的 [am/pm] 样式

\u : 当前使用者的账号名称, 如 [root]
\v : BASH 的版本信息,
\w : 完整的工作目录名称, 有根目录写起的目录名称. 但家目录会议 ~ 取代
\W : 利用 basename 函数取得工作名称, 所以仅会列出最后一个目录名
\# : 下达的第几个指令
\$ : 提示字符, 如果是 root 时, 提示字符为 #, 否则就是 $.

如 ubuntu 预设的 PS1 内容 : \u@\h:\w\$
即为 : 账号名@主机名:完整工作目录提示字符


PS2 即为使用跳脱字符(\)第二行以后的提示字符(> )


23. bash 变量

1. 变量与变量内容以一个等号 = 连接, 如下所示 :
myname=Hennessy
2. 等号两边不能直接接空格, 如下所示为错误 :
myname = Hennessy 或 myname= Hennessy ll
3. 变量名称只能是英文字母与数字, 但是开头字符不能是数字, 如下为错误 :
2myname=Hennessy
4. 变量内容若有空格符可使用双引号 " 或单引号 ' 将变量内容结合起来, 但
 双引号内的特殊字符如 $ 等, 可以保有原本的特性, 如下所示 :
 var="lang is $LANG" 则 echo $var 可得 lang is en_US.UTF-8
 单引号内的特殊字符则仅为一般字符(纯文本), 如下所示 :
 var='lang is $LANG' 则 echo $var 可得 lang is $LANG
5. 可用跳脱字符 \ 将特殊符号(如 Enter, $, \, 空格,' 等)变成一般字符
6. 在一串指令中, 还需要藉由其他指令提供的信息, 可以使用反单引号 `(在一串指令中, 在 ` 之内的指令将会被先执行, 而其执行出来的结果将做为外部的输入信息) 或 $
7. 若该变量为扩增变量内容时, 则可用 "$变量名称" 或 ${变量} 累加内容, 如下所示 :
PATH="$PATH:/home/bin"
8. 若该变量需要在其他子程序执行, 则需要以 export 来使变量成为环境变量 :
export PATH
9. 通常大写字符为系统默认变量, 自行设定变量可以使用小写字符, 方便判断
10. 取消变量的方法为使用 unset : unset 变量名称, 例如取消 myname 的设定 :
unset myname  

变量键盘读取, 数组与宣告 : read, array, declare
read [-pt] variable
-p : 后面可以接提示字符
-t : 后面可以接等待的秒数

declare [-aixr] variable
-a : 将后面名为 variable 的变量定义成为数组(array)类型
-i : 将后面名为 variable 的变量定义成为整数数字(integer)类型
-x : 用法与 export 一样, 就是将后面的 variable 变成环境变量
-r : 将变量设定成为 readonly 类型, 该变量不可被更改内容, 也不能 unset
(将 - 变成 + 可以进行取消的动作, 但如果将变量设定为只读, 通常要注销再登入才能恢复该变量的类型)

1) 变量类型默认为字符串, 若不指定变量类型, 则 1+2 为一个字符串而不是计算式;
2) bash 环境中的数值运算, 预设最多仅能到达整数形态, 所以 1/3 结果是 0.

var[index]=content


24. && 与 ||

指令下达情况                                                                   说明

cmd1 && cmd2                      1. 若 cmd1 执行完毕且正确执行 ($?=0), 则开始执行 cmd2;
                                                 2. 若 cmd2 执行完毕且为错误 ($?!=0), 则 cmd2 不执行.

cmd1 || cmd2                         1. 若 cmd1 执行完毕且为正确执行 ($?=0), 则 cmd2 不执行;
                                                 2. 若 cmd2 执行完毕且为错误 ($?!=0), 则开始执行 cmd2.

例如
1) 不清楚 /tmp/abc 是否存在, 但就是要建立 /tmp/abc/hehe 档案
ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe


2) 以 ls 测试 /tmp/testing 是否存在, 若存在则显示 "exsit", 否则显示 "not exist"
ls /tmp/testing && echo "exist" || echo "not exist"

注意 && 与 || 的顺序不能搞错, 一般来说, 假设判断式有三个, 也就是 :
command1 && command2 || command3, 而且通常顺序不会变


25. 磁盘分区最终写入分割表后会让核心无法捕捉到分割表信息, 此时可以直接使用 reboot 来处理, 也可以使用 GNU 推出的工具程序来处置, 那就是 partprobe 这个指令. 这个指令的执行很简单, 他仅是告知核心必须要读取新的分割表, 因此并不会在屏幕上出现任何信息, 这样以来就不需要再 reboot.


26. 基本上, 指令运作的顺序可以这样看 :
1. 以相对/绝对路径执行指令, 例如 /bin/ls 或 ./ls
2. 由 alias 找到该指令来执行;
3. 由 bash 内建的 (builtin) 指令来执行;
4. 透过 $PATH 这个变量的顺序搜寻到第一个指令来执行.

举例来说, 可以下达 /bin/ls 及单纯的 ls, 可以发现使用 ls 有颜色但是 /bin/ls 则没有颜色. 因为/ bin/ls 是直接取用该指令来下达, 而 ls 会因为 alias ls='ls --color=auto' 这个命令别名而先使用/如果想要了解指令搜寻的顺序, 其实透过 type -a 指令 也可以查询到.


27. bash 的进站与欢迎信息 : /etc/issue, /etc/motd

bash 也有进站欢迎和欢迎信息, 就是在终端机接口 (tty1~tty6) 登入时候出现的几行提示字符串. 这个字符串就写在 /etc/issue 里面.
如同 $PS1 这个变量一样, issue 这个档案的内容也是可以使用反斜杠作为变量取用.

issue 各代码意义

\d本地端时间的日期
\l显示第几个终端机接口
\m显示硬件的等级 (386/i486/i586/i686...)
\n显示主机的网络名称
\o显示 domain name
\r操作系统的版本 (相当于 uname -r)
\t显示本地端时间的时间
\s操作系统的名称
\v操作系统的版本

例如 : Ubuntu 14.04.1 LTS \n \l则应为Ubuntu 14.04.1 LTS  ubuntu tty1

需要注意的是, 除了 /etc/issue 之外还有个 /etc/issue.net, 这是提供给 telnet 这个远程登录程序用的. 当我们使用 telnet 连接到主机时, 主机的登入画面就会显示 /etc/issue.net 而不是 /etc/issue.

至于如果你想要让使用者登入后取得一些信息, 例如你想要让大家都知道的信息, 那么可以将信息加入到 /etc/motd 里面. 



28. bash 的环境配置文件
login shell : 取得 bash 需要完整的登入流程的, 就称为 login shell. 举例来说, 由 tty1 ~ tty6 登入, 需要输入用户的账号与密码, 此时取得的 bash 就称为 login shell.
non-login shell : 取得 bash 接口的方法不需要重复登入的举动, 举例来说, (1) 以 X window 登入 Linux 后, 再以 X 的图形换接口启动终端机, 此时那个终端机接口并没有需要再次的输入账号与密码, 那个 bash 的环境就成为 non-login shell. (2) 在原本的 bash 环境下再次下达 bash 这个指令, 同样的也没有输入账号密码, 那第二个 bash (子程序) 也是 non-login shell.

这两个取得 bash 的情况中, 读取的配置文件数据并不一样.  一般来说, login shell 只会读取这两个配置文件 :
1) /etc/profile : 这是系统整体的设定, 最好不要修改这个档案;
2) ~/.bash_profile 或 ~/.bash_login 或 ~/.profile : 属于使用者个人设定, 若要修改自己的数据, 就写入这里. 而读取的顺序则是依照上面的顺序, 也就是说, 如果 ~/.bash_profile 存在, 那么其他两个档案不论有无存在, 都不会被读取. 如果 ~/.bash_profile 不存在才会去读取 ~/.bash_login, 而前两个都不存在才会读取 ~/.profile. 会有这么多的档案, 其实是应其他 shell 转换过来的使用者的习惯而已.

由于 /etc/profile 与 ~/.bash_profile 都是在取得 login shell 的时候才会读取的配置文件, 所以, 如果你将
自己的偏好设定写入上述的档案后, 通常都是得注销再登入后, 该设定才会生效. 要直接读取配置文件而不注销登入, 就要利用 source 这个指令. (利用 source 或 小数点 . 都可以将配置文件的内容都进目前的 shell 环境中), 在 login shell 环境下, 最终被读取的配置文件是 ~/.bashrc 这个档案.

当你取得 non-login shell 时, 该 bash 配置文件仅会读取 ~/.bashrc. 此外, 还会主动呼叫 /etc/bashrc (Ubuntu 没有此文件,与之对应的是 /ect/bash.bashrc), 因为其帮我们的 bash 定义出底下的数据 :
1) 依据不同的 UID 规范出 umask 的值;
2) 依据不同的 UID 规范出提示字符 (就是 PS1 变量);
3) 呼叫 /etc/profile.d/*.sh 的设定

其他相关配置文件
1) /etc/man.config (Ubuntu 没有此文件, 与之对应的是 /etc/manpath.config), 该档案的内容规范了使用 man 的时候, man page 的路径到哪里寻找, 即该去哪里查看数据的路径.这个档案内最重要的是 MANPATH 这个变量设定;
2) ~/.bash_history 预设情况下, 历史命令就记录在这里. 而这个档案能够记录几笔数据, 则与 HISTFILESIZE 这个变量有关. 每次登入 bash 后, bash 会先读取这个档案, 将所有的历史指令读入内存.
3) ~/bash_logout 这个档案记录了当注销 bash 后, 系统再做完什么动作后才离开. 预设的情况下, bash 只是帮我们清掉屏幕的信息.



29. 终端机的环境设定

stty  -a将目前所有的 stty 参数列出来
几个重要的代表意义是 :
eof (^D) : End of file 的意思, 代表结束输入;
erase (^?) : 向后删除字符 ;
intr (^C) : 送出一个 interrupt (中断)
kill (^U) : 删除在目前指令列上的所有文字;
quit (^\): 送出一个 quit 信号给目前正在 run 的程序;
start (^Q): 在某个程序停止后, 重新启动它的 output;
stop (^S): 停止目前屏幕的输出;
susp (^Z) : 送出一个 termin stop 的信号给正在 run 的程序.


30. 数据流重导向

standard output 与 standard error output
简单的说, 标准输出指的是指令执行所回传的正确的信息, 而标准错误输出可理解为指令执行失败后, 所回传的错误信息. 数据流重导向可以将 standard output (简称 stdout) 与 standard error output (简称 stderr) 分别传送到其他的档案或装置去, 而分别传送所用的特殊字符则如下所示 :
1. 标准输入    (stdin) : 代码为 0, 使用 < 或 <<;
2. 标准输出  (stdout) : 代码为 1, 使用 > 或 >>;
3.标准错误输出(stderr) : 代码为 2, 使用 2> 或 2>>.
其中,
1> : 以覆盖的方式将正确的数据输出到指定的档案或装置上;
1>> : 以累加的方式将正确的数据输出到指定的档案或装置上;
2> : 以覆盖的方式将错误的数据输出到指定的档案或装置上;
2>> : 以覆盖的方式将错误的数据输出到指定的档案或装置上.

注意, 如果知道错误信息会发生, 所以要将错误信息忽略掉而不显示或存储, 这个时候 黑洞装置 /dev/null 就很重要了, 这个 /dev/null 可以吃掉任何导向这个装置的信息.
例如将错误的数据丢弃, 屏幕上只显示正确的数据 find /home -name .bashrc 2> /dev/null
而如果要将正确与错误的数据写入一个档案, 这个时候就需要特殊的写法. 例如架构指令的数据全部写入名为 file 的档案中 find /home -name .bashrc > file 2>&1(也可.使用 &>).

至于 standard input 以最简单的说法来说, 就是将原本需要由键盘输入的数据, 改由档案内容来取代. 例如用 stdin 取代键盘输入以建立新档案 cat > catfile < ~/.bashrc.
至于 << 代表的是结束的输入字符的意思, 举例来说, 要用 cat 直接将输入的信息输出到 catfile 中, 且当由键盘输入 eof 时, 该次输入就结束 cat > catfile << "eof"


使用场合 :

1) 屏幕输出的信息很重要, 而且需要将其保存下来的时候;
2) 背景执行的程序, 不希望他干扰屏幕正常的输出结果时;
3) 一些系统的例行命令 (例如写在 /etc/crontab 中的档案) 的执行结果, 希望其可以存下来时;
4) 一些执行命令的可能已知错误信息时, 想以 2> /dev/null 将他丢掉时;
5) 错误信息与正确信息需要分别输出时. 


31. 管线命令 (pipe)

其实管线命令 | 仅能处理由前面一个指令传来的正确信息, 也就是 standard output 的信息,
对于 standard error output 并没有直接处理的能力. 在每个管线后面接的第一个数据必定是 指令, 而且这个指令必须要能够接受 standard input 的数据才行, 这样的指令才可以是管线命令, 例如 less, more, head, tail 等都是可以接受 standard output 的管线命令. 至于例如 ls, cp, mv 等就不是管线命令, 因为 ls, cp, mv 并不会接受来自 stdin 的数据.

1) 撷取命令 : cut, grep
一般来说, 撷取信息通常是针对一行一行来分析的,  而不是整篇信息分析.

cut 这个指令可以将一段信息的某一段切出来, 处理的信息是以行为单位, 主要的用途在于对同一行里面的数据进行分解, 不过 cut 在处理多空格相连的数据时会比较吃力.
cut -d '分隔字符' -f fields例如 echo $PATH|cut -d ':' -f 3,5

grep 则是分析一行信息, 若当中有我们所需要的信息, 就将改行拿出来.
例如 last|grep --color=auto 'root' |cut -d ' ' -f 1

2) 排序命令 : sort, wc, uniq
3) 字符转换命令 : tr, col, join, paste, expand

4) 双向重导向 : tee
 > 会将数据流整个传送给档案或装置, 因此除非去读取该档案或装置, 否则就无法继续利用这个数据流. 若想要将这个数据流的处理过程中将某段信息存下来, 就可以利用 tee.

tee 会同时将数据流分别送到档案与屏幕 (screen), 而输出到屏幕的, 其实就是 stdout, 可以让下个指令继续处理.

例如 ls -l /home|tee ~/homefile|more
         ls -l /home|tee -a ~/homefile|more (加上 -a 以累加 (append)的方式将数据加入 file当中) 

5) 分割命令 : split

例如 ls -l /home | split -l 10 - lshome

        cat lshome* >> lshome

6) 参数代换 : xargs

产生某个指令的参数, xargs 可以读入 stdin 的数据, 并且以空格符或断行字符作为分辨, 将 stdin 的资料分隔成 arguments. 因为是以空格符作为分隔, 所以, 如果有一些档案名或者是有其他意义的名词内含有空格符时, xargs 可能就会误判.

例如 cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs finger


要会使用 xargs 的原因是, 很多指令其实并不支持管线命令, 但我们可以透过 xargs 来提供该指令引用 standard input 之用.

例如 find /sbin -perm 7000 | xargs ls -l


7) 减号的用途

在管线命令中, 常常会使用到前一个指令的 stdout 作为这次的 stdin, 某些指令需要用到文件名 (例如 tar) 来进行处理时, 该 stdin 与 stdout 可以利用 - 来替代,

例如 tar -cvf - /home | tar -xvf -     将 /home 里面的档案给他打包,但打包癿数据不是记录到档案,而是传送到 stdout; 经过管线后,将 tar -cvf - /home 传送给后面的 tar -xvf -



32. 正规表示法

正规表示法基本上是一种表示法, 只要工具程序支持这种表示法, 那么该工具程序就可以用来作为正规表示法的字符串处理之用. 例如 vi, grep, awk, sed 等等工具, 因为他们有支持正规表示法, 所以这些工具就可以使用正规表示法的特殊字符进行字符串的处理. 但例如 cp, ls 等指令并未支持正规表示法, 所以就只能使用 bash 自几本身的通配符 (Wildcard) 而已.

符号意义
*代表 [0 个到无穷多个] 任意字符
?代表 [一定有一个] 任意字符
[ ]  同样代表 [一定有一个在括号内的字符] (非任意字符)
[ - ]若有减号在中括号内, 代表 [在编码顺序内的所有字符]
[^ ]若中括号内的第一个字符为指数符号 (^), 表示 [反向选择]

正规表示法的字符串表示方式按照不同的严谨度而分为 : 基础正规表示法与延伸正规表示法.延伸正规表示法除了简单的一组字符串处理之外, 还可以作群组的字符串处理, 例如进行搜寻 VBird 或 netman 或 lman 的搜寻.

特殊符号代表意义
[:alnum:]代表英文大小写字符及数字, 亦即 0-9, A-Z, a-z
[:alpha:] 代表任何英文大小写字符, 亦即 A-Z, a-z
[:digit:]代表数字, 亦即 0-9
[:lower:] 代表小写字符, 亦即 a-z
[:upper:] 代表大写字符, 亦即 A-Z

行首与行尾字符 ^ 和 $
1) 注意, ^ 符号在字符集和符号 (括号[]) 之内与之外是不同的. 在 [] 内代表反向选择, 在 [] 之外则代表定位在行首的位置.
2) 例如在档案中找出行尾结束为小数点的那一行grep -n '\.$' regular_express.txt这里因为小数点具有其他意义, 所以必须要使用跳脱字符 (\) 加以解除其特殊意义. 同时由于断行字符在 Linux 与 Windows 上的差异, Windows 的断行字符为 ^M$, 而正常的 Linux 应该仅有 $, 所以小数点 (.) 自然就不是接在 $ 之前, 也就捕捉不到.
3) 例如查找空白行grep -n '^$' regular_express.txt
  查找非空白且以 # 开头的行grep -v '^$' regular_express.txt | grep -v '^#'

在正规表示法中,
. (小数点) : 代表一定有一个任意字符的意思;
* (星号) : 代表重复前一个 0 次到无穷多次的意思.
{} (大括号) : 限制一个范围区间内的重复字符数, 但因为 { 与 } 在 shell 是有特殊意义的, 因此, 必须使用跳脱字符 \ 来让他失去特殊意义才行.

再次强调 : 正规表示法的特殊字符与一般在指令列输入指令的通配符并不相同, 例如, 在通配符中的 * 代表的是 0 ~ 无限多个字符, 但是在正规表示法当中, * 则是重复 0 到无穷多个的前一个 RE 字符.
举例来说, 不支持正规表示法的 ls 这个工具中, 若我们使用 ls -l * 代表的是任意档名的档案, 而 ls -a* 代表的是以 a 开头的任何档名的档案, 但在正规表示法中, 我们要找出含有以 a 开头的档案, 则必须这样 : (需搭配支持正规表示法的工具)ls -l | grep -n '^a.*'

延伸正规表示法 (grep -E 或 egrep)
例如上例的查找非空白且以 # 开头的行grep -v '^$' regular_express.txt | grep -v '^#', 如果使用延伸型的正规表示法, 可以简化为 egrep -v '^$|^#' regular_express.txt延伸正规表示法可以透过群组功能 | 来进行一次搜寻, | 管线意义为 或 or.

RE 字符意义
+重复 [一个或一个以上] 的前一个 RE字符
?[零个或一个] 前一个 RE 字符
|   用或 (or) 的方式找出数个字符串
()找出群组的字符串如 egrep -n 'g(la|oo)d' regular_express.txt
()+ 多个重复群组的判别如 echo 'AxyzxyzxyzC' | egrep 'A(xyz)+C'

要特别强调的是 , ! 在正规表示法当中并不是特殊字符.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值