2.shell
Last updated
Was this helpful?
Last updated
Was this helpful?
[TOC]
什么是shell:
管理整個電腦硬體的其實是作業系統的核心 (kernel),這個核心是需要被保護的,不能夠隨便被一些沒有管理能力的終端用戶隨意使用,但是我們總是需要讓使用者操作系統的,于是就有了在作業系統上面發展的应用程序,而这个程序在kernel外層,就如同雞蛋的外殼一樣,因此這個咚咚也就被稱呼為外壳程序(shell) 。shell中的命令本质也是通过命令控制相应的程序,从这个点来看,只要能操作应用程序的介质都能成为外壳程序。
狭义的shell指的命令行界面的解析器,广义的则包括图形界面,因为图形界面也是调用的应用程序来呼叫kernel工作。
关于终端的维基百科,应该说得更准确:
为什么要学shell:
通用性强 各家 distributions 使用的 bash 都是一樣的(不全是?)
远程管理
远程管理的时候文字传输命令更快
不易掉线、信息保密性更好
文字界面更简洁有效
关于linux预设的shell——bash shell的主要功能:
记忆命令,很多发行版中默认可记忆1k个 放在$HOME/.bash_history中,不过里面的内容是每次登出的时候才会存进去,而本次的命令则是在内存中,可用history
查看
tab键补全
在第一个单词中使用是补全命令
连按两次会显示所有可补全的命令,过多会提示Display all possibilities?(y/n)
在第二个单词中使用是补全档案
其他的补全
$
开头的话,是变量补全
~
开头是用户名字补全
@
开头则是对主机名补全(只对包含在文件/etc/hosts
中的主机名有效)
别名alias
工作控制、前景背景控制: (job control, foreground, background)
程式化腳本: (shell scripts)
通配符: (Wildcard)
待补充
图形界面shell(Graphical User Interface shell 即 GUI shell)
应用最为广泛的 Windows Explorer(windows资源管理器)
命令行式shell(Command Line Interface shell ,即CLI shell)
shell快捷键主要记住这几个就行了:ctrl+a
、ctrl+e
、ctrl+k
、ctrl+u
和ctrl+l
图形界面终端下的多标签切换:ctrl+PgUP/PgDN
或alt+1/2/...
光标移动命令(似乎有问题,待整理)
Ctrl-a
移动光标到行首.
Ctrl-e
移动光标到行尾.
Ctrl-f
光标前移一个字符;和右箭头作用一样.
Ctrl-b
光标后移一个字符;和左箭头作用一样.
Alt-f
光标前移一个字.
Alt-b
光标后移一个字.
Ctrl-l
清空屏幕,移动光标到左上角.clear
命令完成同样的工作.
文本编辑命令
Ctrl-d
删除光标位置的字符。
Ctrl-t
光标位置的字符和光标前面的字符互换位置。
Alt-t
光标位置的字和其前面的字互换位置。
Alt-l
把从光标位置到字尾的字符转换成小写字母。
Alt-u
把从光标位置到字尾的字符转换成大写字母。
剪切和粘贴命令
Ctrl-k
剪切从光标位置到行尾的文本。
Ctrl-u
剪切从光标位置到行首的文本。
Alt-d
剪切从光标位置到词尾的文本。
Alt-Backspace
剪切从光标位置到词头的文本。如果光标在一个单词的开头,剪切`前一个单词。
Ctrl-y
把剪切板中的文本粘贴到光标位置。
自动补全命令
Alt-?
显示可能的自动补全列表。在大多数系统中,你也可以完成这个通过按 两次 tab 键,这会更容易些。
Alt-*
插入所有可能的自动补全。当你想要使用多个可能的匹配项时,这个很有帮助。
撤销上次编辑:Ctrl+-
当我们登入的时候,系统就会指派一个shell来为我们工作,记录在/etc/passwd
里
echo $0
:如果是在shell中则输出shell的名字,如果是在脚本中,则输出脚本的文件名。比如在bash中执行echo $0
,输出的是“-bash”。
通过网络登录或者终端登录建立的会话,会分配唯一一个tty终端或者pts伪终端(网络登录),实际上它们都是虚拟的,以文件的形式建立在/dev目录,而并非实际的物理终端。
在终端中按下的特殊按键:中断键(ctrl+c)、退出键(ctrl+\)、终端挂起键(ctrl + z)会发送给当前终端连接的会话中的前台进程组中的所有进程
在网络登录程序中,登录认证守护程序 fork 一个进程处理连接,并以ptys_open 函数打开一个伪终端设备(文件)获得文件句柄,并将此句柄复制到子进程中作为标准输入、标准输出、标准错误,所以位于此控制终端进程下的所有子进程将可以持有终端
与控制终端相连的会话首进程也叫控制进程
fork是linux的系统调用,用来创建子进程(child process)。子进程是父进程(parent process)的一个副本,从父进程那里获得一定的资源分配以及继承父进程的环境。子进程与父进程唯一不同的地方在于pid(process id)。环境变量(传给子进程的变量,遗传性是本地变量和环境变量的根本区别)只能单向从父进程传给子进程。不管子进程的环境变量如何变化,都不会影响父进程的环境变量。
bash shell的命令分为两类:外部命令和内部命令。
内部命令实际上是shell程序的一部分,其中包含的是一些比较简练的UNIX系统命令,这些命令由shell程序识别并在shell程序内部完成运行,通常在UNIX系统加载运行时shell就被加载并驻留在系统内存中。外部命令是UNIX系统中的实用程序部分,因为实用程序的功能通常都比较强大,所以它们包含的程序量也会很大,在系统加载时并不随系统一起被加载到内存中,而是在需要时才将其调进内存。通常外部命令的实体并不包含在shell中,但是其命令执行过程是由shell 程序控制的。shell程序管理外部命令执行的路径查找、加载存放,并控制命令的执行。
外部命令是通过系统调用或独立的程序实现的,如sed、awk等等。内部命令是由特殊的文件格式(.def)所实现,如cd、history、exec、source等等。
sh是一种POSIX标准,它有很多种实现,包括ksh88, dash,bash等。
因为sh是一种规范,并不是实现,所以/bin/sh
实际上是一个硬链接,链接到某种实现上。大多数情况下,/bin/sh
会链接到/bin/bash
。所以你执行sh xx
等价于执行bash xx
。但是在一些系统中,/bin/sh并没有指向/bin/bash,比如在一些现代的Debian和Ubuntu系统中,sh指向的是dash。
ubuntu中文wiki的shell指南:https://wiki.ubuntu.org.cn/Shell%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80
&&
、||
和;
对于command1 $$ command2
,当command1执行成功时才会执行command2
对于command1 || command2
,当command1执行失败时才会执行command2
对于command1 ; command2
,顺序执行,不管command1执行是否成功,command2都会执行
对于复杂文件操作很有用,使得shell的命令行变得很强大,因为shell频繁使用文件名.通配符所依赖的工作机制叫做路径名展开.
常用通配符
*
匹配任意多个字符(包括零个或一个)
?
匹配任意一个字符(不包括零个)
[characters]
匹配任意一个属于字符集中的字符
[!characters]
匹配任意一个不是字符集中的字符
[[:class:]]
匹配任意一个属于指定字符类中的字符
常用的字符类
[:alnum:]
匹配任意一个字母或数字
[:alpha:]
匹配任意一个字母
[:digit:]
匹配任意一个数字
[:lower:]
匹配任意一个小写字母
[:upper:]
匹配任意一个大写字母
通配符例子
*
所有文件
g*
文件名以“g”开头的文件
b*.txt
以"b"开头,中间有零个或任意多个字符,并以".txt"结尾的文件
Data???
以“Data”开头,其后紧接着3个字符的文件
[abc]*
文件名以"a","b",或"c"开头的文件
BACKUP.[0-9][0-9][0-9]
以"BACKUP."开头,并紧接着3个数字的文件
[[:upper:]]*
以大写字母开头的文件
[![:digit:]]*
不以数字开头的文件
*[[:lower:]123]
文件名以小写字母结尾,或以 “1”,“2”,或 “3” 结尾的文件
尽量避免使用[a-z]
和[A-Z]
这种写法,它是早期的unix环境中的写法(而且也不稳定),现在推荐使用字符类
通配符在一些图形文件管理器中也有效,比如gnome的Nautilus中的Edit/Select 模式
通配符总是以有序的方式展开.比如movie.mpeg.0*
,则所有匹配项会有序排列
-c
:它可以让 bash 将一个字串作为完整的命令来执行。
脚本调试
-x
在执行脚本的过程中把它实际执行的每一个命令行显示出来,并且在行首显示一个”+”号。 “+”号后面显示的是经过了变量替换之后的命令行的内容,有助于分析实际执行的是什么命令。它是调试shell脚本的强有力参数。关闭显示使用+x
test和[]都是测试的意思,比如
[ -d dir ]
等价于test -d dest
:如果dir是目录则为真
字符展开和引用可以说是shell最重要的主题
可能原因:输入了错误的指令,比如q!
输成!q
如何在执行一个命令的时候还可以执行另外一个命令,比如说git clone的时候我想像eclipse那样实时显示进度,我写进了python,怎么能在之后执行呢?
程式化腳本: (shell scripts)
$(dirname $0)表示存放脚本文件的目录
(待补充)
bash参考手册,是一本参考书,同时包含了很多实例:
bashFAQ,包含很多常见问题的答案,面向中高级用户:
GNU完整命令行列表:
维基百科关于手册页的有趣文章: