`
姜太公
  • 浏览: 73893 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

Bash系列:从命令行开始

阅读更多
Shell的精髓在于命令行
       ---无名氏语
 
先从几个简单的命令开始,认识Shell中命令
echo hello 
echo -n hello
rm -f hello; touch hello
curl http://www.google.com/ | less
 
选项和参数
先看第一个,这个最简单了,它只是简单打印一个hello字符串。其中echo是命令部分,hello是参数部分。
第二个命令之比第一个多了一个-n,一般我们把-n叫做选项,这个选项告诉echo命令输出完hello之后不要擅作主张再输出个换行符。
到这里有必要说明下选项和参数,两者有什么联系和区别呢。
从以前的经验中我们也能感觉到,选项对命令的功能起到一定的定制作用,在命令基本功能的基础上加一点定制化的东西。比如上面的echo命令,它的基本功能就是把参数打印出来,-n这个选项定制了:不要输出默认情况下会输出的换行符。ls的基本功能是列出当前目录下的内容,-l选项定制:输出比较详细的信息。如果我自己写了一个程序myecho,它的功能是逐行输出给定的参数。C 代码如下:

#include<stdio.h>

int main(int argc,char *argv[])
{
 int i=0;
 for(i=0; i<argc; i++)
 {
  printf("%s\n", argv[i]);
 }
 return 0;
}

gcc -o myecho myecho.c

./myecho -n hello world

输出:

./myecho                                                                                                                        
-n                                                                                                                              
hello                                                                                                                           
world
这里输出的,就是程序接收到的参数列表。可见,长的很像“选项”的-n在这里也和hello一样,都是普通参数。在代码层面上,只有参数,没有选项,所谓选项,只不多是程序为了增强自己的适应性,主动设定了一些特殊参数,当这些特殊参数存在时,就执行相应的定制功能。
在Shell里,常见的有三种风格的选项:
1   UNIX风格, 用中划线开始的可分组形式,比如grep -oP,也可以写作grep -o -P
2   BSD风格,不带中划线的可分组形式,比如ps aux,也可以写作ps a u x
3   GNU风格,两个中划线加长单词,比如grep --ignore-case,等效于grep -i,优点是可读性较好,缺点是写起来比较麻烦
每种命令都有自己支持的选项,命令不同,选项的风格也不同,有些命令支持多种风格的选项,比如ps支持上面全部三种,grep支持unix和gnu风格的选项。使用命令前最好--help一下,看看命令支持哪些选项。
 
一些概念
    先约定两个名词:语句表示在Shell输入的整个一行内容,命令则是指一个可行的指令。比如在命令行中输入less -f log|grep sql然后回车,那么less -f log|grep sql是一个语句,less和grep则是其中的命令。
 
简单命令
 
先看这条语句:
echo -n hello > abc &
echo是命令(它可能是磁盘的程序,也可能是shell内建的命令),-n和hello是参数,>是重定向描述符,&表示后台执行。
这条语句虽然包含的成分比较多,但它只有一个命令(可执行部分)。像这种只有一个可执行部分的语句叫做简单命令(Simple command),是Shell里的执行单元
 
退出状态
退出状态是shell中一个很重要概念。 每个命令结束时都会返回给操作系统一个 退出状态码 (有时候也被称为 返回状态 ). 一般约定成功的命令返回0, 而不成功的命令返回非零值, 非零值通常都被解释成一个错误码. 行为良好的UNIX命令, 程序, 和工具都会返回0作为退出码来表示成功, 虽然偶尔也会有例外。之所以退出状态很重要,因为Shell是根据退出状态作为判断命令是否成功执行的依据,很多场合里,退出状态起到布尔值的作用,比如 if,while,for都用命令的退出状态。特殊变量?(没错,就是一个问号)里保存了上一个命令的退出状态,在命令行里,可以执行echo $?查看变量?的值。
 
前面说到简单命令,它的退出状态是这样的:如果命令执行完毕,自己退出,它的退出状态就是它返回给操作系统的退出状态。如果它是执行过程中被信号KILL掉,它的退出状态就是128+信号值。
例子:
jjz@JJZ:~$ echo hello
hello
jjz@JJZ:~$ echo $?
0                                        #这里的0就是echo的退出状态。
jjz@JJZ:~$
 
再来个有信号的例子:

 

jjz@JJZ:~$ sort
^C                                      #这里按下ctrl+C
jjz@JJZ:~$ echo $?
130                                    #ctrl+C是信号SIGINT,它的值是2,所以退出状态时128+2=130。可以用man 7 singal查看所有标准信号的值。                                                        

 
 
管道
管道可谓是Shell中最激动人心的特性,正因为有了管道,Shell才能把众多的Linux工具整合起来,完成强大的功能。
curl http://www.google.com/ | less 就是用了管道。显然,这不是一个简单命令,因为它有两个可执行部分:curl和less。简单的来说,管道的作用是把前一个命令的标准输出重定向到后一个命令的标准输入,也就是前一个命令的输入当成了后一个命令的输入。关于管道和重定向的细节,详见后文。
 
一般情况下管道的退出状态是最后一个执行的命令的退出状态。 (二般情况和bash的一个名叫pipefail的选项有关,这东西太少用,此处不再赘述)
 
命令列表
顾名思义,命令列表就是把命令写成一个列表(汗...),rm -f hello; touch hello就是命令列表,这里使用了分号作为命令分隔符。除了分号外,还可以使用||和&&。
rm -f hello || touch hello
rm -f hello && hello
 
三者的区别在于分号只是纯粹的分割,前面命令的执行效果不会对后面的命令产生影响。而||和&&具有布尔表达式的短路效果,还记得Java 里的判断吗
if (a&&b)... 这种情况下,如果a是false,那么表达式a&&b的值就是false,不会再测试b。
if (a||b)... 这种枪口下,如果a是true,那么表达死a||b的值就是true,不会再测试b。
和java里的判断类似,对于&&来说,只有第一个命令执行成功(退出状态是0),才会执行第二个命令,否则不执行第二个命令。||就刚好相反,如果第一个命令执行失败(退出状态非0),才会执行第二个命令,否则不会执行第二个命令。
 
列表的退出状态是列表中最后一个执行的命令的退出状态。对于a&&b,如果a的退出状态非0,b根本不会执行,a才是最后一个执行的命令,列表的退出状态就是a的退出状态。
 
复合命令
复合命令的形式比较多,控制结构也算复合结构。
(list): 在子Shell中执行命令列表(里面也可以是简单命令),简单的说,就是当前Shell会创建一个新的Shell进程,在新的Shell进程里执行 list里的命令。意义何在?如果修改了环境变量,可以保证当前环境变量不会对括号里的命令产生影响。
当然,也可以在括号里先设置一些环境变量,给里面的命令使用,而且不会对当前环境造成影响。
 
{list}:在当前环境执行,和普通的命令列表不同的是,这里的list构成一个“组”,可以简单的认为它们就是一个命令(当然,还是有顺序执行的)。
{ echo helo; echo world; }>abc 文件abc的内容有两行,分别是hello和world
echo helo; echo world; >abc  abc的内容是空的
 
两者的退出状态都是其中的命令列表的退出状态。
 
关于{}还有一点要注意的是花括号{}和list直接要有空格,而且最后一个命令后面必须有分号; 圆括号()这无此限制。要解释这个,就要说说Bash的元字符(Metacharacter)和保留字(Reserved  words)
 
元字符,保留字,引用
Shell中命令和参数使用空格(space)或制表符(tab)分隔的。这两中字符叫做"blank"
有些字符具有特殊的含义,用来分隔token,叫做元字符。下面都是元字符
|  & ; ( ) < > space tab
 
Shell处理命令行的第一步就是用元字符把语句分隔成多个token,比如语句 curl http://www.google.com/ | less,Shell首先用元字符把它分成如下token: curl, http://www.google.com/, |和 less。后面讲到Shell如何处理语句时会详细解释,详见后文。
 
还有些字符具有特殊含义,执行控制功能,叫做控制字符,下面都是控制字符
|| & && ; ;; ( ) | |& <newline>
 很明显,控制字符的作用就是控制。 比如|就有管道的作用, &具有使命令后台执行的功能。它们两个同时也是元字符,立场很不坚定。
 
每种语言都有保留字,在 java里,while,if等都是保留字,Shell当然也有自己的保留字,如下所示:
! case  do done elif else esac fi for function if in select then until while { } time [[ ]]
 
保留字本身没甚么特别之处,只是程序语言说:“这些单词和符号我自己用,你们不准使用”,于是它们就成了保留字。

 

引用
这个概念出镜率非常高。
如果我想输出一个左圆括号(,直接执行 echo (是不行的,不信你可以试试,(在Shell里是特殊字符,这时候就需要引用"上场"了:echo '('或者echo "("都可以。
引用难道就是字符两边加上单引号或双引号?这个答案算部分正确,引用的目的是去除元字符和保留字的特殊意义,加引号只是手段罢了。关于引用的详细描述,以及单引号和双引号的区别。详见后文。
分享到:
评论

相关推荐

    蔡氏电路matlab仿真代码-Git-basic:使用命令行记录您的git操作

    使用命令行记录您的git操作 1.什么是Git? 您的团队有一个项目,团队中的每个成员都必须从事该项目。 就像这个人在编辑一些东西,添加几行代码。 手动地,当A先生进行一些修改时,必须通知整个小组。 A先生将把新...

    笔记、Laravel、PHP、面试题、MySQL、HTML、CSS、Java

    10段超有用的Git命令行代码 #3 MySQL 相关: MySQL基础命令 Rust 相关: Rust 学习笔记及示例代码: Learning Rust 。 Bash 相关: 本人翻译的 Bash 中文指南 ,不错的 linux bash 命令入门材料。 Vue 相关: Vu

    fish-shell:用户友好的命令行shell

    -友好的互动外壳 fish是适用于macOS,Linux和该系列其他产品的智能且用户友好的命令行外壳。 fish包括语法高亮显示,键入时自动建议和花哨的制表符补全等功能,这些功能可以正常工作,而无需进行配置。 有关fish的...

    linux Bash脚本判别使用者的身份方法示例

    经常要在bash脚本里面或者直接对脚本本身...首先要说下经验:命令行的权限执行,从表现上来看,可以分为以下5种情况: admin-manual: 普通用户手敲命令 sudo-manual: 手敲命令加sudo admin-bash: 以普通用户执行bas

    ShellOut:通过Swift脚本或命令行工具轻松运行Shell命令

    欢迎使用ShellOut,这是一个简单的软件包,可让您轻松地从Swift脚本或命令行工具中“淘汰”。 即使您可以完成本机Swift代码中需要完成的大多数任务,但有时您仍需要从脚本或工具中调用命令行的功能-这正是ShellOut...

    new_script:Bash shell 脚本模板生成器

    Bash shell 脚本模板生成器 ========== 这是一个shell脚本模板生成器(即编写脚本的脚本)。 它用于创建 shell 脚本的样板部分。 它向用户询问有关要生成的脚本的一系列问题,然后将生成的脚本写入文件。 使用 new_...

    spotify-tools:Linux 上 Spotify 的 bash 脚本集合

    Spotify:trade_mark: 工具一系列与 Linux 上的 Spotify 交互的 bash 脚本。目录安装通过下载.zip文件或克隆整个存储库来查看此存储库的最新版本将脚本文件夹放在您选择的位置安装您计划使用的任何脚本所需的所有依赖...

    Linux系统管理工具包系列汇总 Linux系统管理员必看

    存在各种用于简化不同过程的关键实用工具、命令行链和脚本。其中一些工具来自于操作系统,而大部分的诀窍则来源于长期的经验积累和减轻系统管理员工作压力的要求。本系列文章主要专注于最大限度地利用各种Linux环境...

    hash:Hash – 快乐的 shell 脚本语言

    目标是设计一种现代语言,可以在一系列脚本中取代 Bash:从简单的单行代码到复杂的多模块项目。 哈希脚本将编译为 Bash 脚本,以便于部署和跨平台兼容性。 一般来说,设计目标是: 使 shell 脚本编写方便、可读和...

    install-scripts:一系列安装脚本

    从命令行轻松安装应用程序 用法 4kvideodownloader (GUI) 4kvideodownloader-ubuntu wget -qO - https://git.io/JTlFT ? =4kvideodownloader-ubuntu | bash aws-cli aws-cli-linux wget -qO - ...

    用户友好的命令行外壳。-Linux开发

    fish包括语法高亮显示,键入时自动提示和标签选项卡com fish等功能-友好的交互式shell fish是适用于macOS,Linux和该系列其他产品的智能且用户友好的命令行shell。 fish包括语法高亮显示,键入时自动建议和花哨的...

    mac-setup:一系列bash脚本,用于引导新的OS X 10.11系统

    如果尚未安装[Xcode命令行工具],请安装它。 打开Xcode并接受许可协议。引导新系统打开Terminal.app,然后粘贴以下命令: curl -fsSL https://raw.github.com/rbartoli/setup/master/setup/bootstrap.sh | sh

    cpu_upup2.sh

    调节CPU频率,可以强制将CPU的频率设置为高性能 ...开机后,命令行运行之 ''' bash cpu_upup2.sh ''' 安装相关包等一系列操作都封装进去了,一个命令完美解决~ (这个.sh脚本的文件名可以改成自己喜欢的)

    有效外壳:“有效外壳”系列的文字,示例和网站

    我的“有效外壳”系列的文字,示例和参考。 该网站托管于 。 介绍 该存储库包含联机丛书的所有内容。 可以从下载包含所有示例effective-shell-playground文件夹。 分享中 分享时,我倾向于使用以下标签: #...

    ARM_Linux启动分析.pdf

    在arch/alpha/vmlinux.lds 的链接脚本控制下,链接程序将vmlinux的入口置于 "arch/alpha/kernel/head.S"中的__start上,因此当Bootloader跳转到0x100000时, __start处的代码开始执行。__start的代码很简单,只需要...

    shebang-everything:您的非官方shell脚本指南,如果可以帮助您,请给此仓库一个:white_medium_star::)

    因此,基本上,脚本是一个命令行程序,其中包含要执行的一系列命令。 这些命令由解释器执行。 您可以在命令行中输入的任何内容都可以在脚本中输入。 而且,脚本非常适合自动化任务。 如果发现自己经常重复执行某些...

    shiyan1.rar_shiyan1

    实现一个简单的shell(命令行解释器),类似于bash, csh等。本设计的主要目的在于学会如何在Unix系统下创建进程和管理进程。 要求实现的shell支持以下内部命令: 1. cd &lt;目录&gt; 更改当前的工作目录到另一个&lt;...

    README-Generator

    安装后,您将能够在GitBash或您选择的命令行中运行node index命令。 系统将提示您回答一系列问题,这些问题将自动填充新生成的README.md文件。 然后,您将在./dist/README.md位置中找到更新的文件。 重要的是,您...

    reproducible_research:Riffomonas可复制研究指南系列的网站

    本次研讨会将重点关注命令行实践(例如bash),脚本语言(例如mothur,R),版本控制(例如git),自动化(例如make)和文化编程(例如Rmarkdown)的重要性。 这些是Schloss实验室中使用的工具,可帮助提高手稿的可...

Global site tag (gtag.js) - Google Analytics