欢迎您的光临,本博所发布之文章皆为作者亲测通过,如有错误,欢迎通过各种方式指正。

教程  Shell&Shell脚本基础教程——常用功能用法

Shell 本站 1318 0评论

1.Bash常用快捷键及其作用


在 Bash 中有非常多的快捷键,如果可以熟练地使用这些快捷键,可有效地提高我们的工作效率。只是快捷键相对较多,不太好记忆,这就要多加练习和使用。这些快捷键如表 1 所示。


表 1 Bash 常用快捷键
快捷键作 用
Ctrl+A把光标移动到命令行开头。如果我们输入的命令过长,则在想要把光标移动到命令行开头时使用
Ctrl+E把光标移动到命令行结尾
Ctrl+C强制中止当前的命令
Ctrl+L淸屏,相当于 clear 命令
Ctrl+U刪除或剪切光标之前的命令。假设输入了一行很长的命令,无须使用退格键一个一个字符地刪除, 使用这个快捷键会更加方便
Ctrl+K删除或剪切光标之后的内容
Qrl+Y粘贴 Ctrl+U 或 Ctrl+K 剪切的内容
Ctrl+R在历史命令中搜索,按下 Ctrl+R 组合键之后,就会出现搜索界面,只要输入搜索内容,就会从历史命令中搜索
Ctrl+D退出当前终端
Ctrl+Z暂停,并放入后台。这个快捷键涉及工作管理的内容,我们会在后续中详细介绍
Ctrl+S暂停屏幕输出
Ctrl+Q恢复屏幕输出


Shell自定义快捷键方法

首先,我们要学会查看 Shell 中已有快捷键的方法,如下所示:

[root@localhost ~]# stty -a
#查询所有的快捷键
speed 38400 baud; rows 21; columns 1.04; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>;
start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time =0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -cdtrdsr
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc —ixany -imaxbel
-iutf8
opost -Olcuc -ocrnl onlcr -onocr -Onlret -ofill -ofdel nlO crO tabO bsO vtO ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

"-a"选项用于査询系统中所有可用的快捷键,可以看到,"Ctrl+C"用于强制中止,"Ctrl+D"用于中止输入。那么,这些快捷键可以更改吗?


当然可以,只需执行以下命令即可:

[root@localhost ~] # stty 关键字 快捷键
例如:
[root01ocalhost ~]# stty intr ^p
#定义Ctrl +P快提键为强制中止,"^"字符只需手工输入即可
[root@localhost ~】# stty -a
speed 38400 baud; rows 21; columns 104; line = 0;
intr = ^P; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>;
start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
#强制中止的快提键变成了Ctrl+P


2.单引号、双引号和反引号用法


单引号和双引号用于变量值出现空格时,比如 name=zhang san 这样执行就会出现问题,而必须用引号括起来,比如 name="zhang san"。


不过,引号有单引号和双引号之分,二者的主要区别在于,被单引号括起来的字符都是普通字符,就算特殊字符也不再有特殊含义;而被双引号括起来的字符中,"$"、"\"和反引号是拥有特殊含义的,"$"代表引用变量的值,而反引号代表引用命令。还是来看例子吧:

[root@localhost ~]# name=sc
#定义变量name的值是sc
[root@localhost ~]# echo '$name'
$name
#如果输出时使用单引号,则$name原封不动地输出
[root@localhost ~]# echo "$name"
sc
#如果输出时使用双引号,则会输出变量name的值sc
[root@localhost ~]# echo `date`
2013 10月 21 日星期一 18:16:33 CST
#反引号的命令会正常执行
[root@localhost ~]# echo '`date`'
'date'
#但是如果反引号括起来的命令又被单引号括起来,那么这条命令不会执行,`date`会被当成普通字符输出
[root@localhost ~]# echo "`date`"
2013年 10月 21 日星期一 18:14:21 CST
#如果被双引号括起来,那么这条命令又会正常执行


所以,如果需要在双引号中间输出"$"和反引号,则要在符号前加入转义符"\"。


反引号

如果需要调用命令的输出,或把命令的输出赋予变量,则命令必须使用反引号包含,这条命令才会执行,反引号的作用和 $(命令) 是一样的,但是反引号非常容易和单引号搞混,所以推荐大家使用 $(命令) 的方式引用命令的输出。命令如下:

[root@localhost ~]# echo ls
ls

如果命令不用反引号包含,那么命令不会执行,而是直接输出

[root@localhost -]# echo `ls`
anaconda-ks.cfg install.log install.log.syslog sh test testfile
#只有用反引号包含命令,这条命令才会执行
[root@localhost ~]# echo $(date)
2013年 10月 21 日 星期一 18:25:09 CST
#使用用$(命令)的方式也是可以的


3.Shell(Bash)小括号和大括号用法及区别


在介绍小括号和大括号的用法及区别之前,我们先解释两个概念:父 Shell 和子 Shell。

在 Bash 中,是可以调用新的 Bash 的,比如:

[root@localhost ~]# bash
[root@localhost ~]#


这时,可以通过 pstree 命令査看一下进程数,命令如下:

[root@localhost ~]# pstree
init──┬──abrt-dump-oops
…省略部分输出
├─sshd──┬──sshd───bash───bash───pstree
…省略部分输出

可以看到我们的命令都是通过 ssh 远程服务链接的,在 ssh 中生成了第一个 Bash,就是父 Shell。因为我们刚刚执行了 Bash 命令,所以在第一个 Bash 中生成了第二个 Bash,这个 Bash 就是子 Shell,我们是在子 Shell 中运行命令 pstree 的。


关于父 Shell 和子 Shell,大家可以想象成在 Windows 中我们开启了一个"cmd"字符操作终端,那么 Windows 本身就是父 Shell,而"cmd"终端则是子 Shell;也可以理解为在一个操作界面中又开启了一个操作界面。


知道了父 Shell 和子 Shell,我们接着解释小括号和大括号的区别。如果用于一串命令的执行,那么小括号和大括号主要区别在于:

() 执行一串命令时,需要重新开启一个子 Shell 来执行。

{} 执行一串命令时,在当前 Shell 中执行。

() 和 {} 都是把一串命令放田括号里面,并且命令之间用";"隔开。

() 最后一条命令可以不用分号。

{} 最后一条命令要用分号。

{} 的第一条命令和左括号之间必须有一个空格。

() 里的各命令不必和括号有空格。

() 和 {} 中括号里面的某条命令的重定向只影响该命令,但括号外的重定向则会影响到括号里的所有命令。


下面举几个例子。

[root@localhost ~]# name=sc #在父 Shell 中定义 name 的值是 sc
[root@localhost ~]# (name=liming;echo $name)
liming
#如果用()括起来一串命令,那么这些命令都可以执行
#给name变量重新赋值,但是这个值只在子Shell中
[root@localhost ~]# echo $name
sc
#父Shell中name的值还是sc,而不是liming
[root@localhost ~]#{ name=liming;echo $name;} liming
#但是用大括号来进行一串命令的执行时,name变量的修改是直接在父Shell中进行的
#注意大括号的格式
[root@localhost ~]# echo $name
liming
#name变量的值已经被修改了


其实在执行一串命令时,如果使用的是小括号,则这串命令所做的修改只在子 Shell 中生效,一旦命令执行结束,回到父 Shell 中,这个修改就会丟失;而如果使用的是大括号,则此串命令直接在父 Shell 中执行,命令执行结束后,修改依然会生效。


4.Bash命令自动补全操作


在 Bash 中,命令与文件补全是非常方便与常用的功能,我们只要在输入命令或文件时按 Tab,就会自动进行补全。


命令补全是按照 PATH 环境变量所定义的路径查找命令的(后续章节详细介绍),而文件补全是按照文件位置查找文件的。

比如,想要知道以 user 开头的命令有多少,就可以执行以下操作:

[root@localhost ~]# user
#输入user,按Tab键,如果以user开头的只有一条命令,就会不全这条命令
#如果以user开头的有多条命令,则只要按两次Tab键,就会列出所有以user开头的命令
useradd userdel userhelper usermod usemetctl users


不仅命令可以补全,文件和目录也可以用 Tab 键进行补全。大家一定要多用 Tab 进行补全,这样不仅可以加快输入速度,而且会减少输入错误。所以,养成使用 Tab 的习惯,对 Linux 的管理和使用都有很大的帮助。


5.Shell(Bash)管道符用法


在 Bash 中,管道符使用"丨"代表。管道符也是用来连接多条命令的,如"命令1丨命令2"。不过和多命令顺序执行不同的是,用管道符连接的命令,命令 1 的正确输出作为命令 2 的操作对象。这里需要注意,命令 1 必须有正确输出,而命令 2 必须可以处理命令 1 的输出结果;而且命令 2 只能处理命令 1 的正确输出,而不能处理错误输出。


举个例子,我们经常需要使用"||"命令査看文件的长格式,不过在有些目录中文件众多,比如 /etc/ 目录,使用"ll"命令显示的内容就会非常多,只能看到最后的内容,而不能看到前面输出的内容。

这时,我们马上想到 more 命令可以分屏显示文件内容,可是怎么让 more 命令分屏显示命令的输出呢?我想到了一种笨办法:

[root@localhost ~]# ll -a /etc/ > /root/testfile
#用输出重定向,把ll命令的输出保存到/root/testfile 文件中
[root@localhost ~]# more /root/testfile
#既然testfile是文件,当然可以用more命令分屏显示了
总用量1784
drwxr-xr-x. 105 root root 1228810月 21 12:49. dr-xr-xr-x. 26 root root 4096 6月519:06..
…省略部分输出…
-rwxr-xr-x. 1 root root 687 6月 22 2012 auto.smb --More--(7%)


可是这样操作实在不方便,这时就可以利用管道符了。命令如下:

[root@localhost ~]# ll -a /etc/|more

这条命令大家可以这样理解:先把"ll -a /etc"命令 的输出保存到某个临时文件中,再用 more 命令处理这个文件。也就是我们说的第一个命令的正确输出是第二条命令处理和操作的对象。


注意,ll 命令操作的是文件名,所以匹配时使用的是通配符。但是一旦加入管道符,管道符之后的内容相当于操作的是文件内容,所以匹配时使用的是正则表达式。


关于管道符,我们再举几个例子:

[root@localhost ~]# netstat -an | grep "ESTABLISHED"
#查询一下本地所有网络连接,提取包含 ESTABLISHED(已建立连接)的行
#就可以知道我们的服务器上有多少已经成功连接的网络连接
[root@localhost ~]# netstat -an | grep "ESTABLISHED" | wc-l
#如果想知道具体的网络连接数量,就可以再使用wc命令统计行数


6.Shell通配符用法分析


在 Bash 中,如果需要模糊匹配文件名或目录名,就要用到通配符。通过表 1 介绍一下常用的通配符。

表 1 通配符
通配符作 用
?匹配一个任意字符
*匹配 0 个或任意多个任意字符,也就是可以匹配任何内容
[]匹配中括号中任意一个字符。例如,[abc] 代表一定匹配一个字符,或者是 a,或者是 b,或 者是 c
[-]匹配中括号中任意一个字符,- 代表一个范围。例如,[a-z] 代表匹配一个小写字母
[^]逻辑非,表示匹配不是中括号内的一个字符。例如,[^0-9] 代表匹配一个不是数字的字符


举几个例子:

[root@localhost ~]# cd /tmp/
[root@localhost tmp]# rm -rf *
#进入临时目录,删除所有文件
#这个也是通配符,代表当前目录中的所有文件
[root@localhost tmp]# touch abc
[root@localhost tmp]# touch abcd
[root@localhost tmp]# touch 012
[root@localhost tmp]# touch 0abc
#建立几个测试文件
[root@localhost tmp]# ls *
012 0abc abc abed
#"*"代表所有的文件
[root@localhost tmp]# ls ?abc
0abc
#"?"匹配任意一个字符,所以会匹配 0abc,但是不能匹配 abc,因为"?"不能匹配空
[root@localhost tmp]# ls [0-9]* 012 0abc
#匹配任何以数字开头的文件
[root@localhost tmp]# ls [^0-9]* abc abcd
#匹配不以数字开头的文件


7.Shell 输入/输出重定向


大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。


重定向命令列表如下:


命令说明
command > file将输出重定向到 file。
command < file将输入重定向到 file。
command >> file将输出以追加的方式重定向到 file。
n > file将文件描述符为 n 的文件重定向到 file。
n >> file将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m将输出文件 m 和 n 合并。
n <& m将输入文件 m 和 n 合并。
<< tag将开始标记 tag 和结束标记 tag 之间的内容作为输入。


需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。


1)输出重定向

重定向一般通过在命令间插入特定的符号来实现。特别的,这些符号的语法如下所示:

command1 > file1

上面这个命令执行command1然后将输出的内容存入file1。

注意任何file1内的已经存在的内容将被新内容替代。如果要将新内容添加在文件末尾,请使用>>操作符。


实例:

执行下面的 who 命令,它将命令的完整的输出重定向在用户文件中(users):

$ who > users

执行后,并没有在终端输出信息,这是因为输出已被从默认的标准输出设备(终端)重定向到指定的文件。

你可以使用 cat 命令查看文件内容:

$ cat users
_mbsetupuser console  Oct 31 17:35 
tianqixin    console  Oct 31 17:35 
tianqixin    ttys000  Dec  1 11:33


输出重定向会覆盖文件内容,请看下面的例子:

$ echo "ittxx.cn" > users
$ cat users
ittxx.cn
$


如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾,例如:

$ echo "ittxx.cn" >> users
$ cat users
ittxx.cn
ittxx.cn
$


2)输入重定向

和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:

command1 < file1

这样,本来需要从键盘获取输入的命令会转移到文件读取内容。

注意:输出重定向是大于号(>),输入重定向是小于号(<)。


实例:

接着以上实例,我们需要统计 users 文件的行数,执行以下命令:

$ wc -l users
       2 users

也可以将输入重定向到 users 文件:

$  wc -l < users
       2

注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。

command1 < infile > outfile

同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中。


3)重定向深入讲解

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

· 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。

· 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。

· 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。


如果希望 stderr 重定向到 file,可以这样写:

$ command 2 > file


如果希望 stderr 追加到 file 文件末尾,可以这样写:

$ command 2 >> file

2 表示标准错误文件(stderr)。


如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:

$ command > file 2>&1

或者

$ command >> file 2>&1


如果希望对 stdin 和 stdout 都重定向,可以这样写:

$ command < file1 >file2

command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。


4)Here Document

Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。

它的基本的形式如下:

command << delimiter

    document

delimiter

它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。

注意:

结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。

开始的delimiter前后的空格会被忽略掉。


实例:

在命令行中通过 wc -l 命令计算 Here Document 的行数:

$ wc -l << EOF
    欢迎来到
    ittxx.cn
EOF
2          # 输出结果为 2 行
$



我们也可以将 Here Document 用在脚本中,例如:

#!/bin/bash
# url:ittxx.cn
cat << EOF
欢迎来到
ittxx.cn
EOF

执行以上脚本,输出结果:

欢迎来到

ittxx.cn


5)/dev/null 文件

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:

$ command > /dev/null

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。


如果希望屏蔽 stdout 和 stderr,可以这样写:

$ command > /dev/null 2>&1

注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。


8.Shell的文件包含


Shell 也可以包含外部脚本,将外部脚本的内容合并到当前脚本。使用:

. filename

#或

source filename


1. 两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格。

2. 被包含脚本不需要有执行权限。


实例:

创建两个 shell 脚本文件。


test1.sh 代码如下:

#!/bin/bash
url="http://www.ittxx.cn"


test2.sh 代码如下:

#!/bin/bash
#使用 . 号来引用test1.sh 文件
. ./test1.sh
# 或者使用以下包含文件代码
# source ./test1.sh
echo "官网地址:$url"


接下来,我们为 test2.sh 添加可执行权限并执行:

$ chmod +x test2.sh 
$ ./test2.sh 
官网地址:http://www.ittxx.cn


注:被包含的文件 test1.sh 不需要可执行权限。


转载请注明: ITTXX.CN--分享互联网 » Shell&Shell脚本基础教程——常用功能用法

最后更新:2018-12-25 12:07:12

赞 (6) or 分享 ()
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽