Linux里shell定义命令什么时候要加双引号

Shell是命令解释器(command interpreter)是Unix操作系统的用戶接口,程序从用户接口得到输入信息shell将用户程序及其输入翻译成操作系统内核(kernel)能够识别的指令,并且操作系统内核执行完将返回嘚输出通过shell再呈现给用户下图所示用户、shell和操作系统的关系:

一个系统可以存在多个shell,可以通过cat /etc/shells命令查看系统中安装的shell不同的shell可能支歭的命令语法是不相同的

操作系统内核(kernel)与shell是独立的套件,而且都可被替换:

不同的操作系统使用不同的shell;

同一个kernel之上可以使用不同的shell

常见的shell分为两大主流:

所谓临时变量是指在用户在当前登陆环境生效的变量,用户登陆系统后直接在命令行上定义的环境变量便只能茬当前的登陆环境中使用。当退出系统后环境变量将不能下次登陆时继续使用。

通过将环境变量定义写入到配置文件中用户每次登陆時系统自动定义,则无需再到命令行重新定义定义环境变量的常见配置文件如下:

/etc/profile  针对系统所有用户生效,此文件应用于所有用户每次登陆系统时的环境变量定义   系统环境变量

系统环境变量对所有用户有效如:$PATH、$HOME、$SHELL、$PWD等等,如下用echo命令打印上述的系统环境变量:

同传统嘚编程语言一样shell提供了很多特性,这些特性可以使你的shell脚本编程更为有用

一个shell脚本通常包含如下部分:

第一行内容在脚本的首行左侧,表示脚本将要调用的shell解释器内容如下:

#!符号能够被内核识别成是一个脚本的开始,这一行必须位于脚本的首行/bin/bash是bash程序的绝对路径,在这里表示后续的内容将通过bash程序解释执行

注释符号# 放在需注释内容的前面,如下:

可执行内容和shell结构

一般情况下默认创建的脚本昰没有执行权限的

没有权限不能执行,需要赋予可执行权限

1 输入脚本的绝对路径或相对路径

注:当脚本没有x权限时root和文件所有者通过该方式可以正常执行。

区别:第一种和第二种会新开一个bash不同bash中的变量无法共享

但是使用第三种方式 脚本.sh 这种方式是在同一个shell里面执行的。

变量:是shell传递数据的一种方式用来代表每个取值的符号名。

当shell脚本需要保存一些信息时如一个文件名或是一个数字,就把它存放在┅个变量中

1,变量名称可以由字母数字和下划线组成,但是不能以数字开头环境变量名建议大写,便于区分

2,在bash中变量的默认類型都是字符串型,如果要进行数值运算则必须指定变量类型为数值型。

3变量用等号连接值,等号左右两侧不能有空格

4,变量的值洳果有空格需要使用单引号或者双引号包括。//注意要是英文输入法那种

Linux Shell中的变量分为用户自定义变量,环境变量位置参数变量和预定义變量

可以通过set命令查看系统中存在的所有变量

系统变量:保存和系统操作环境相关的数据$HOME、$PWD、$SHELL、$USER等等

位置参数变量:主要用来向脚本Φ传递参数或数据,变量名不能自定义变量作用固定。

预定义变量:是Bash中已经定义好的变量变量名不能自定义,变量作用也是固定的

用户自定义的变量由字母或下划线开头,由字母数字或下划线序列组成,并且大小写字母意义不同变量名长度没有限制。

习惯上用夶写字母来命名变量变量名以字母表示的字符开头,不能用数字

在使用变量时,要在变量名前加上前缀“$”.

2, 将一个命令的执行结果赋給变量

A=`ls -la` 反引号运行里面的命令,并把结果返回给变量A

3将一个变量赋给另一个变量

单引号和双引号的区别:

现象:单引号里的内容会  全蔀输出,而双引号里的内容会有变化

原因:单引号会将所有特殊字符脱意

用户自定义的变量作用域为当前的shell环境。

用户自定义变量只在當前的shell中生效而环境变量会在当前shell和其所有子shell中生效。如果把环境变量写入相应的配置文件那么这个环境变量就会在所有的shell中生效。

莋用域:当前shell以及所有的子shell

n为数字$0代表命令本身,$1-$9代表第一到第9个参数,

十以上的参数需要用大括号包含如${10}。

代表命令行中所有的参数把所有的参数看成一个整体。以"$1 $2 … $n"的形式输出所有参数

代表命令行中的所有参数把每个参数区分对待。以"$1" "$2" … "$n" 的形式输出所有参数

代表命令行中所有参数的个数添加到shell的参数个数

shift指令:参数左移,每执行一次参数序列顺次左移一个位置,$# 的值减1用于分别处理每个参數,移出去的参数不再可用

$* 和 $@ 都表示传递给函数或脚本的所有参数不被双引号" "包含时,都以"$1" "$2" … "$n" 的形式输出所有参数

当它们被双引号" "包含時"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开以"$1" "$2" … "$n" 的形式输出所有参数

shell脚本中执行测试:

执行上一個命令的返回值   执行成功,返回0执行失败,返回非0(具体数字由命令决定)

当前进程的进程号(PID)即当前脚本执行时生成的进程号

后囼运行的最后一个进程的进程号(PID),最近一个被放入后台执行的进程   &

Linux文件默认是没有x权限的 而文件是有的

按住Ctrl +退格 才可以退

expr命令:对整數型变量进行算术运算

(注意:运算符前后必须要有空格) 

计算(2 +3 )×4 的值

$( )的用途和反引号``一样用来表示优先执行的命令

内置test命令常用操莋符号[]表示,将表达式写在[]中如下:

测试范围:整数、字符串、文件

表达式的结果为真,则test的返回值为0否则为非0。

当表达式的结果为嫃时则变量$?的值就为0,否则为非0

&& 逻辑与 条件满足才执行后面的语句

||  逻辑或,条件不满足才执行后面的语句

如下示例两个变量值的大尛比较:

条件1 –a 条件2 逻辑与  两个都成立,则为真

条件1 –o 条件2 逻辑或   只要有一个为真则为真

1, 单分支if条件语句

单分支条件语句需要注意几個点

if语句使用fi结尾和一般语言使用大括号结尾不同。

[ 条件判断式 ] 就是使用test命令判断所以中括号和条件判断式之间必须有空格

then后面跟符號条件之后执行的程序,可以放在[]之后用“;”分割,也可以换行写入就不需要";"了。

2,多分支if条件语句

    当所有条件都不成立时最后执荇此程序

case命令是一个多分支的if/else命令,case变量的值用来匹配value1,value2,value3等等匹配到后则执行跟在后面的命令直到遇到双分号为止(;;)case命令以esac作为终止符。

for循環命令用来在一个列表条目中执行有限次数的命令比如,你可能会在一个姓名列表或文件列表中循环执行同个命令for命令后紧跟一个自萣义变量、一个关键字in和一个字符串列表(可以是变量)。第一次执行for循环时字符串列表中的第一个字符串会赋值给自定义变量,然后執行循环命令直到遇到done语句;第二次执行for循环时,会右推字符串列表中的第二个字符串给自定义变量依次类推,直到字符串列表遍历唍

练习:计算从1到100的加和。

while命令根据紧跟其后的命令(command)来判断是否执行while循环当command执行后的返回值(exit status)为0时,则执行while循环语句块直到遇到done语句,然后再返回到while命令判断command的返回值,当得打返回值为非0时则终止while循环。

练习:求1-10 各个数的平方和

函数代表着一个或一组命令的集合表示一个功能模块,常用于模块化编程

在shell中,函数必须先定义再调用

函数在当前shell中执行,可以使用脚本中的变量

如果函数名后没有(),在函数名和{ 之间必须要有空格以示区分。

函数返回值只能通过$? 系统变量获得,可以显示加:return 返回值如果不加,将以最后一条命令运行结果作为返回值。 return后跟数值n(0-255)

这将执行该脚本并显示所有变量的值

不执行脚本只是检查语法的模式,将返回所有语法错误

一個强大的文本分析工具

把文件逐行的读入,以空格为默认分隔符将每行切片空格可以是连续的空格切开的部分再进行各种分析处理。

语法:awk ‘条件1{动作1}条件2{动作2}...’文件名

FS内置变量 //默认第一行不会进行分割

 输出可登陆用户的用户名和UID,这里使用FS内置变量指定分隔符为:,而且使鼡BEGIN保证第一行也操作因为awk命令会在读取第一行后再执行条件

指定分隔符还可以用-F更简单

eg:判断一下根目录的使用情况

END 在所有数据执行之后執行

获取所有用户信息里的用户名:

获取当前机器的ip地址:

s e d是一个非交互性文本编辑器。它编辑文件或标准输入导出的文本拷贝标准輸入可 能是来自键盘、文件重定向、字符串或变量,或者是一个管道的文本

注意: s e d 并不与初始化文件打交道, 它操作的只是一个拷贝嘫后所有的改动如果没有重定向到一个文件,将输出到屏幕

语法:sed [选项]’[动作]’ 文件名

-n  使用安静(silent)模式。显示经过sed特殊处理的数據

-e  允许多点编辑。

-i  直接修改读取的档案内容而不是由屏幕输出。

新增 a 的后面可以接字串,在下一行出现

插入 i 的后面可以接字串

使用sed获取机器的ip地址

crontab 命令允许用户提交、编辑或删除相应的作业。每一个用户都可以有一个crontab 文件来保存调度信息可以使用它运行任意一个 s h e l l 脚本或某个命令。

作用:用于生成cron进程所需要的crontab文件

使用编辑器编辑当前的crontab文件

1,全都不能为空,必须填入不知道的值使用通配符*表示任何时间
2,每个时间字段都可以指定多个值,不连续的值用,间隔连续的值用-间隔。
3,命令应该给出绝对路径
4,用户必须具有运行所对應的命令或程序的权限

如何使用crontab 运行多个任务:

方法2:把所有的任务写入到一个可执行的文件

eg:每周二,周五下午6点  的计划任务

eg:1到3月份,烸周二周五下午6点的计划任务

eg:周一到周五下午,5点半提醒学生15分钟后关机

eg:学校的计划任务 12点14点,检查apache服务是否启动

eg:再添加一个备份紦/etc目录备份到/backup下,然后把错误的情况也记录下来正确的文件都丢到/dev/null下,看不见(相当于一个黑洞)  

}

shell 脚本的基础知识

日常的linux系统管理笁作中必不可少的就是shell脚本如果不会写shell脚本,那么你就不算一个合格的管理员目前很多单位在招聘linux系统管理员时,shell脚本的编写是必考嘚项目有的单位甚至用shell脚本的编写能力来衡量这个linux系统管理员的经验是否丰富。笔者讲这些的目的只有一个那就是让你认真对待shell脚本,从一开始就要把基础知识掌握牢固然后要不断的练习,只要你shell脚本写的好相信你的linux求职路就会轻松的多。笔者在这一章中并不会多麼详细的介绍shell脚本而只是带你进入shell脚本的世界,如果你很感兴趣那么请到网上下载相关的资料或者到书店购买相关书籍吧

在学习shell 脚本の前,需要你了解很多关于shell的知识这些知识是编写shell脚本的基础,所以希望你能够熟练的掌握

简单点理解,就是系统跟交互时使用的中間介质它只是系统的一个工具。实际上在shell和之间还有一层东西那就是系统内核了。打个比方如果把比作一个人的躯体,而系统内核則是人的大脑至于shell,把它比作人的五官似乎更加贴切些回到计算机上来,用户直接面对的不是而是shell用户把指令告诉shell,然后shell再传输给系统内核接着内核再去支配计算机硬件去执行各种操作。

我们敲过的命令linux是会有记录的,预设可以记录1000条历史命令这些命令保存在鼡户的家目录中的.bash_history文件中。有一点需要你知道的是只有当用户正常退出当前shell时,在当前shell中运行的命令才会保存至.bash_history文件中

与命令历史有關的有一个有意思的字符那就是”!”了。常用的有这么几个应用:(1)!! (连续两个”!”)表示执行上一条指令;(2)!n(这里的n是数字),表示执行命令历史中第n条指令例如”!100”表示执行命令历史中第100个命令;(3)!字符串(字符串大于等于1),例如!ta表示执行命令历史中朂近一次以ta为开头的指令。

在本教程最开始笔者就介绍过这个功能了记得吗?对了就是按tab键它可以帮你补全一个指令,也可以帮你补铨一个路径或者一个文件名连续按两次tab键,系统则会把所有的指令或者文件名都列出来

前面也出现过alias的介绍,这个就是bash所特有的功能の一了我们可以通过alias把一个常用的并且很长的指令别名一个简洁易记的指令。如果不想用了还可以用unalias解除别名功能。直接敲alias会看到目湔系统预设的alias :


看到了吧系统预设的alias指令也就这几个而已,你也可以自定义你想要的指令别名alias语法很简单,alias [命令别名]=[’具体的命令’]

在bash下,可以使用*来匹配零个或多个字符而用?匹配一个字符。

用于改变命令的输入输出重定向用于改变命令的输出。输出重定向更为瑺用它经常用于将命令的结果输入到文件中,而不是屏幕上的命令是<,输出重定向的命令是>另外还有错误重定向2>,以及追加重定向>>稍后会详细介绍。

前面已经提过过管道符”|”就是把前面的的结果丢给后面的命令。

当运行一个进程时你可以使它暂停(按Ctrl+z),然後使用fg命令恢复它利用bg命令使他到后台运行,你也可以使它终止(按Ctrl+c)

前面章节中笔者曾经介绍过环境变量PATH,这个环境变量就是shell预设嘚一个变量通常shell预设的变量都是大写的。变量说简单点就是使用一个较简单的字符串来替代某些具有特殊意义的设定以及数据。就拿PATH來讲这个PATH就代替了所有常用命令的绝对路径的设定。因为有了PATH这个变量所以我们运行某个命令时不再去输入全局路径,直接敲命令名即可你可以使用echo命令显示变量的值。

使用env命令即可全部列出系统预设的全部系统变量了不过登录的用户不一样这些环境变量的值也不┅样。当前显示的就是root这个账户的环境变量了下面笔者简单介绍一下常见的环境变量:

PATH 决定了shell将到哪些目录中寻找命令或程序

HOME 当前用户主目录

LANG 语言相关的环境变量,多语言可以修改此环境变量

MAIL 当前用户的邮件存放目录

env命令显示的变量只是环境变量系统预设的变量其实还囿很多,你可以使用set命令把系统预设的全部变量都显示出来

限于篇幅,笔者在上例中并没有把所有显示结果都截图set不仅可以显示系统預设的变量,也可以连同用户自定义的变量显示出来用户自定义变量?是的用户自己同样可以定义变量。

虽然你可以自定义变量但昰该变量只能在当前shell中生效,不信你再登录一个shell试试

使用bash命令即可再打开一个shell,此时先前设置的myname变量已经不存在了退出当前shell回到原来嘚shell,myname变量还在那要想设置的变量一直生效怎么办?有两种情况:

1)要想系统内所有用户登录后都能使用该变量

2)只想让当前用户使用该變量

需要在用户主目录下的.bashrc文件最后一行加入“export myname=Aming” 然后运行”source .bashrc”就可以生效了这时候再登录test账户,myname变量则不会生效了上面用的source命令的莋用是,讲目前设定的配置刷新即不用注销再登录也能生效。

笔者在上例中使用”myname=Aming”来设置变量myname那么在linux下设置自定义变量有哪些规则呢?

a. 设定变量的格式为”a=b”其中a为变量名,b为变量的内容等号两边不能有空格;

b. 变量名只能由英、数字以及组成,而且不能以数字开頭;

c. 当变量内容带有(如空格)时需要加上单引号;

有一种情况,需要你注意就是变量内容中本身带有单引号,这就需要用到了

d. 如果变量内容中需要用到其他结果则可以使用反引号;

e. 变量内容可以累加其他变量的内容,需要加;

在这里如果你不小心把加错为单引号將得不到你想要的结果

通过上面几个例子也许你能看得出,单引号和的区别:用双引号时不会取消掉里面出现的的本身作用(这里的$)洏使用单引号则里面的全部失去它本身的作用。

在前面的例子中笔者多次使用了bash命令如果在当前shell中运行bash指令后,则会进入一个新的shell这個shell就是原来shell的子shell了,不妨你用pstree指令来查看一下

pstree这个指令会把linux系统中所有进程通过树形结构打印出来。限于篇幅笔者没有全部列出你可鉯直接输入pstree查看即可。在父shell中设定一个变量后进入子shell后该变量是不会生效的,如果想让这个变量在子shell中生效则要用到export指令笔者曾经在湔面用过。

export其实就是声明一下这个变量的意思让该shell的子shell也知道变量abc的值是123.如果export后面不加任何变量名,则它会声明所有的变量

在最后面連同我们自定义的变量都被声明了。

前面光讲如何设置变量如果想取消某个变量怎么办?只要输入”unset 变量名”即可

系统环境变量与個人环境变量的配置文件

上面讲了很多系统的变量,那么在linux系统中这些变量被存到了哪里呢,为什么用户一登陆shell就自动有了这些变量呢

\u就是用户,\h 主机名 \W 则是当前目录,\$就是那个’#’了如果是普通用户则显示为’$’

除了两个系统级别的配置文件外,每个用户的主目录下还有几个这样的隐藏文件:

.bash_profile:定义了用户的个人化路径与环境变量的文件名称每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次。

.bashrc:该文件包含专用于你的shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取例如你可以将用户洎定义的alias或者自定义变量写到这个文件中。

.bash_logout :当退出shell时会执行该文件。可以把一些清理的工作放到这个文件中

你在学习linux的过程中,也許你已经接触过某个特殊例如”*”,它是一个通配代表零个或多个字符或数字。下面笔者就说一说常用到的

1. * :代表零个或多个字符戓数字。

test后面可以没有任何字符也可以有多个字符,总之有或没有都能匹配出来

2. ? :只代表一个任意的字符

不管是数字还是字母,只要昰一个都能匹配出来

3. # :这个在linux中表示注释说明的意思,即”#”后面的内容linux忽略掉

在命令的开头或者中间插入”#” ,linux都会忽略掉的这個符号在shell脚本中用的很多。

4. \ :脱意字符将后面的特殊符号(例如”*” )还原为普通字符。

sed, awk为正则表达式必须掌握的工具在后续内容中詳细介绍。

6. $ :除了用于变量前面的标识符外还有一个妙用,就是和’!’结合起来使用

‘!$’表示上条命中中最后一个变量(也许称为变量不合适,总之就是上条命令中最后出现的那个东西)例如上边命令最后是test.txt那么在当前命令下输入!$则代表test.txt

1grep:过滤一个或多个字符,将會在后续内容中详细介绍其用法

2) cut:截取某一个字段

-d :后面跟分隔字符,分隔字符要用双引号括起来

-c :后面接的是第几个字符

-f :后面接的昰第几个区块

-d 后面跟分隔字符这里使用作为分割字符,-f 1 就是截取第一段-f和1之间的空格可有可无。

-c 后面可以是1个数字n也可以是一个区間n1-n2,还可以是多个数字n1,n2,n3

4) wc:统计文档的行数、字符数、词数常用的选项为:

5 uniq:去重复的行,笔者常用的选项只有一个:

-c :统计重复的行數并把行数写在前面

有一点需要注意,在进行uniq之前需要先用sort排序然后才能uniq,否则你将得不到你想要的笔者上面的试验当中已经是排序过所以省略掉那步了。

6tee :后跟文件名类似与重定向”>”,但是比重定向多了一个功能在把文件写入后面所跟的文件中的同时,还顯示在屏幕上

7tr :替换字符,常用来处理文档中出现的特殊符号如DOS文档中出现的^M符号。常用的选项有两个:

-d :删除某个字符-d 后面跟偠删除的字符

-s :把重复的字符去掉

当然替换一个字符也是完全可以的。

不过替换、删除以及去重复都是针对一个字符来讲的有一定局限性。如果是针对一个字符串就不再管用了所以笔者建议只是简单了解这个tr即可,以后你还会学到更多可以实现针对字符串操作的工具

-b :依据大小来分割文档,单位为byte

-l :依据行数来分割文档

6. :平时我们都是在一行中敲一个命令,然后回车就运行了那么想在一行中运荇两个或两个以上的命令如何呢?则需要在命令之间加一个”;”了

8. & :如果想把一条命令放到后台执行的话,则需要加上这个符号通常鼡于时间非常长的情况。

使用jobs可以查看当前shell中后台执行的任务用fg可以调到前台执行。这里的sleep命令就是休眠的意思后面跟数字,单位为秒常用语循环的shell脚本中。

此时你按一下CTRL +z 使之暂停然后再输入bg可以再次进入后台执行。

如果是多任务情况下想要把任务调到前台执行嘚话,fg后面跟任务号任务号可以使用jobs命令得到。

2>>:前面讲过重定向符号> 以及>> 分别表示取代和追加的意思然后还有两个符号就是这里嘚2> 和 2>> 分别表示错误重定向和错误追加重定向,当我们运行一个命令报错时报错信息会输出到当前的屏幕,如果想重定向到一个文本里则要用2>或者2>>。

10. [ ]:中括号中间为字符组合,代表中间字符中的任意一个

在上面刚刚提到了分号用于多条命令间的分隔符。另外还有两個可以用于多条命令中间的特殊符号那就是 “&&”和”||”。下面笔者把这几种情况全列出:

}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信