标签归档:shell

Shell 功能、配置和插件-演道网

关于shell,一个广义的解释就是在用户与操作系统之间,提供一个工具或接口给用户来操作计算机系统;用户在shell中通过输入命令行,按下回车键,shell执行命令后就能返回结果,达到操作计算机的效果。
但有很多人会问,为什么要学习shell呢?以下是我对为什么要学习shell的看法:

  • 在通过ssh来远程操纵Linux/Unix服务器时,都是使用shell而不是用户界面
  • 相比于通过点击多个用户界面来执行操作,输入命令行更加直接和快捷
  • 利用管道组合各种可用工具,来创建和定制宏工具
  • 使用shell script将重复简单的任务自动化

而shell有很多种:Bourne Shell, C Shell,Korn Shell,Bourne-again Shell,TENEX C Shell等,通过命令cat /etc/shells可以查看系统支持哪些shell:

System Support Shell.png

Linux/Unix默认都是使用Bash(Bourne-again Shell),但我更倾向于使用zsh,但由于配置过于复杂,前期很少人使用,但后来有外国程序员弄出一个Oh My ZSH来管理zsh的配置和支持更多插件,使得zsh变得更容易使用和更加强大。

zsh shell.png

Shell有哪些功能

  • 命令历史记录

    一旦你在shell敲入正确命令并能执行后,shell就会存储你所敲入命令的历史记录(存放在~/.bash_history文件),方便你再次运行之前的命令。
    你可以按方向键来查看之前执行过的命令

Shell Command History.gif

可以用!!来执行上一条命令,但最常用还是使用ctrl-r来搜索命令历史记录

Shell Search Command History.gif
  • 命令和文件补全(按tab键)

    当你输入命令或文件名时,你可以通过按tab键来补全命令或文件名,这样可以让你更快敲入命令和敲入正确的命令。
    有时你忘记具体某个命令,但你记住命令开头的几个字母是gi,可以敲入字母gi,按tab键来显示与前几个字母有关的所有命令:

    Shell Command Complete.gif

    当用cd命令前往某个目录时,你不必敲入整个路径的所有目录名,你只需敲入目录前几个字母,然后按tab键逐个补全目录名即可。

    Shell Auto Complete Dir.gif
  • 命令别名

    命令别名是一个比较有用的东西,特别适应用于简化命令输入。比如,你要更新cocoapods时,在shell输入以下命令行

    pod update --verbose --no-repo-update

    但每次都输入这么长的命令行,多么麻烦啊。所以,这时使用命令别名来简化命令行的输入:

    alias pod_update='pod update --verbose --no-repo-update'

    下次你只需要输入pod_update就可以更新cocoapod
    你可以使用alias命令来显示所有命令别名

    list all alias .png
  • 任务控制(job control)

    使用shell登陆系统后,想要一边复制文件、一边查找文件、一边进行编译代码、一边下载软件,当然可以通过开启多个shell来完成,但如果想只在一个shell来完成以上多个任务时,此时可以使用shell的一个特性任务控制

    在学会如何使用命令来控制任务之前,先了解两个概念:前台(foreground)后台(background)前台就是出现提示符让用户操作的环境,而后台就是不能与用户交互的环境,你无法使用 ctrl-c 终止它,可使用 bg/fg 呼叫该任务。

    下面介绍一些命令如何控制任务:

    1. 将任务放在后台运行:命令行 + &

    job control 1.png

    注意一下上面打印信息,[1]表示job number(任务编号),7089表示PID(进程号)。在后台执行的命令,如果有stdout和stderr,数据依旧输出到屏幕上,可以通过数据重定向传输到文件中,就不会影响前台的工作。

    job control 2.png
    2. 将任务丢到后台暂停:ctrl-z

    在shell中执行find / -print命令,然后按下ctrl-z将任务丢到后台暂停:

    job control 3.png

    由上面打印可知,任务find / -print暂停执行,并将任务放在后台,返回一个job number[2]

    3. 查看后台所有任务状态:jobs -l

    输入jobs -l 查看后台所有的任务状态:

    job control 4.png

    仔细查看打印信息,有没有留意到在PID 74177431之前有-+两个符号,-表示最近第二个被放到后台的任务号码,+表示最近被放到后台的任务号码。

    4. 将后台的任务拿到前台处理:fg %jobnumber

    输入fg会默认取出+的任务,然后迅速按下ctrl-z

    job control 5.png

    看上面打印的PID7431,确实如此。再次输入jobs -l来查看后台所有任务的信息

    job control 6.png

    这次输入fg %1来讲后台的任务拿到前台处理。

    5. 将后台的任务变成运行中:bg %jobnumber

    输入jobs -l查看任务状态:

    job control 7.png

    然后输入bg %2; jobs -l将后台任务变成运行,并查看任务状态,然后不断地输入打印信息,这时需要关闭终端才能kill这个shell进程的子进程。

    6. 管理后台当中的任务:kill -signal %jobnumber

    有时,任务在后台运行或暂停,这时我想结束这个任务,怎样办呢?你可以使用kill命令将任务结束。
    输入find / -print命令,并按下ctrl-z暂停任务:

    job control 8.png

    输入kill -9 %1;jobs -l结束任务并显示任务状态:

    job control 9.png
  • shell script

    shell script是利用shell的功能所编写的一个程序,这个程序使用纯文本文件来保存一些shell的命令,并遵循shell的语法规则,搭配数据重定向、管道、和正则表达式等功能来组合各种工具,实现简单重复任务的自动化。

  • 通配符

    除了完整的字符串之外,shell还支持许多的通配符来帮助用户查询和命令执行。我简答地列出常用的几个通配符:

符号 含义
* 表示0到无穷多个任意字符
? 表示有一个任意字符
[] 表示有一个在中括号内的字符。例如[abc]表示有个字符,可能是abc其中一个
[-] 表示在编码顺序内的所有字符。例如[1-7]表示有个字符,范围1到7其中一个
[^] 表示反向选择。例如表示有一个字符,只要不是a,b,c的其他字符都可以

iTerm 2(for mac) && Oh My Zsh

如果你是mac的用户,推荐一个终端应用iTerm 2, iTerm 2 相比mac自带的 Terminal 应用,有太多优点了。例如,支持画面分割,可以设置主题,各种使用的快捷键,以及快速唤出。配合 Oh My Zsh 使用,简直优雅到爆!

Oh My Zsh安装

  • curl方式
    curl -L https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | sh
  • wget方式
    wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O - | sh

    安装完之后,关闭当前终端,并重新打开一个,oh my zsh的默认主题是robbyrussell,效果如下:

robbyrussell theme.jpg

配置

如果你想定制和扩展zsh,oh my zsh提供配置文件~/.zshrc来配置,可以设置环境变量和别名;

# Support autojump
[[ -s ~/.autojump/etc/profile.d/autojump.sh ]] && . ~/.autojump/etc/profile.d/autojump.sh

# setup moco alias name
alias moco_service="moco start -p 12306 -g settings.json"

#setup macvim alias name
alias vim="/Applications/MacVim.app/Contents/MacOS/Vim"

#setup pod update alias name
alias pod_update='pod update --verbose --no-repo-update'

Themes列出所有可用主题,每个主题都有截屏效果并教你如何设置,选择你喜欢的主题,在配置文件~/.zshrc查找字符串ZSH_THEME="robbyrussell",通过改变ZSH_THEME环境变量来改变主题。例如,

ZSH_THEME="agnoster"

oh my zsh提供数十种主题,相关文件在~/.oh-my-zsh/themes 目录,可以编辑主题来满足自身需求,我是使用默认的robbyrussell,不过做了一点小小改动:

PROMPT='%{$fg_bold[red]%}➜ %{$fg_bold[green]%}%p%{$fg[cyan]%}%d %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%}% %{$reset_color%}> '
#PROMPT='${ret_status}%{$fg_bold[green]%}%p %{$fg[cyan]%}%c %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}> '

与原来不同的是,将c(表示当前目录)改为d(表示绝对路径),另外在尾部添加一个>作为隔离符号,效果如下:

modified robbyrussell.png

插件

oh my zsh提供丰富的插件,存放在~/.oh-my-zsh/plugins目录下:

oh my zsh plugins.png

想了解每个插件的功能以及如何使用,只要打开相关插件的目录下zsh文件即可,以git插件为例:

git plugin.png

打开git.plugin.zsh文件,里面有很多命名别来来简化命令的输入。你可以根据自己的需要来启用哪些插件,只需在~/.zshrc配置文件追加内容即可:

plugins=(git autojump osx)

我来介绍一下一些常用插件的使用吧:

git

当你处在一个git受控的目录下时,Shell明确显示gitbranch信息,另外简化git很多命令,具体使用请参考:Plugin:git

autojump

autojump插件使你能够快速切换路径,再也不需要逐个敲入目录,只需敲入目标目录,就可以迅速切换目录。

  • 安装
    如果你是mac用户,可以使用brew安装:
    brew install autojump

    如果是linux用户,首先下载autojump最近版本,比如:

    git clone git://github.com/joelthelion/autojump.git

    然后进入目录,执行

    ./install.py

    最近将以下代码加入~/.zshrc配置文件:

    [[ -s ~/.autojump/etc/profile.d/autojump.sh ]] && . ~/.autojump/etc/profile.d/autojump.sh
  • 使用
    如果你之前打开过~/.oh-my-zsh/themes目录,现在只需敲入j themes就可以快速切换到~/.oh-my-zsh/themes目录。

    autojump.png
osx
  • tab – 在一个新标签打开当前目录
  • cdf – cd到当前Finder目录
  • quick-look – 快速浏览特殊的文件
  • man-preview – 在Preview应用打开特定的man page
  • trash – 将特定的文件移到垃圾桶

使用

  1. 因为zsh兼容bash,所以之前使用bash的人切换到zsh毫无压力
  2. 智能拼写纠正,比如你输入cls,会提示

    auto correct.png
  3. 各种补全:除了支持命令补全和文件补全之外,还支持命令参数补全,插件内容补全,只需要按tab
  4. 使用autojump智能跳转
  5. 目录浏览和跳转:输入d,就显示在会话里访问的目录列表,输入列表前的序号,即可以跳转

    list dir and jump.png
  6. 输入..可以返回到上级目录

    parent dir.png

    YouTube有个演示视频 zsh shell详细介绍如果使用Oh My Zsh

总结

作为的一个程序员,我觉得shell是一个必不可少的工具,使用它能够毫不费劲地操作计算机。在shell提示下,通过调用各种各样的工具,并结合管道,将这些工具根据自己需要组合起来,创建和制定宏工具,甚至编写shell script来将简单而重复的工作自动化,做到Don’t repeat your self

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

Shell变量、数据重定向和管道-演道网

在上一篇博客Shell功能、配置和插件中,介绍了为什么要使用shell,shell有哪些功能,如何使用oh my zsh来提高效率等,本篇重点介绍,shell中的变量的如何设置和读取数据,读取之后如何使用变量?每个程序一般都有输入和输出,让我们看看数据重定向如何处理输入和输出的?还有,Unix/Linux系统提供丰富的工具,我们如何将这些工具通过管道来组合成更加强大的宏工具呢?下面,由我来逐一详细介绍变量、数据重定向和管道。

Variable & Redirection & Pipe.png

Variable & Redirection & Pipe.png

变量

变量的作用

变量与其他程序设计语言一样,都是存储数据,然后被程序引用。相比于不使用变量,而是直接使用数据,存在两个问题:

  1. 当数据改变时,直接使用数据的时候却不能灵活地根据数据改变而随着改变,而使用变量却不同,它能够做到这点。
  2. 当数据发生变化时,如果想保证数据一致性,必须查找所有引用该数据的所有地方,然后将它修改,当下一次再需要修改时,也是像这种情况一样,是多么繁琐的事,而变量却不用,只需要修改变量值即可。

因此,变量具有可变性易于修改的两个特点。

变量的分类

在shell中,大概分为两种变量:环境变量局部变量,主要区别在于它们的使用范围不同,环境变量可以在父进程与子进程之间共享,而自定义变量只在本进程使用。举一个简单的例子来说明:

no share variable.png

no share variable.png

我首先设置一个shell变量devname=sam,然后输入bash打开一个新的shell,而这个shell是子进程,然后echo $devname输出变量值,变量值为空,最后exit退出子进程。

share variable.png

share variable.png

但使用export devname设置环境变量后,再次进入输入bash进入子进程之后,echo $devname输出变量值,这次变量值是sam

查看环境变量envset

如果想查看系统中以及自定义有哪些环境变量,可以使用env命令:

env command.png

env command.png

set命令不仅能查看环境变量,还可以查看与shell接口有关的变量,下面只截取一部分变量:

set command.png

set command.png

变量有哪些操作

显示echo $variable

如果你想显示某个变量的值,例如PATH,你只需要输入:

echo $PATH
echo command.png

echo command.png

注意上面一条命令,需要在变量名前加上一个符号$,这样才能访问变量

设置variable=value和取消unset

如果你想设置某个变量的值,只需在变量名和变量值之间用符号=连接就行了,例如:

set variable.png

set variable.png

由上面的输入命令echo $devname,显示结果为。由此可知,一开始如果没有设置某个变量时,它的是为。另外,设置变量的规则还需要几点注意:

  1. 在命名变量名时,变量名称只能是英文字母和数字,而且首字母不能是数字。下面演示一个错误的例子:

    wrong variable name.png

    wrong variable name.png
  2. 等号=两边不能有空格

    blank can't exist.png

    blank can’t exist.png
  3. 如果变量值有空格,可用双引号" "或单引号' '来包围变量值,但两者是有区别:
    双引号" "内的一些特殊字符,可以保持原有的特性,例如:

    double quotation marks.png

    double quotation marks.png

    而单引号' '内的一些特殊字符,仅为一般字符,即纯文本,例如:

    single quotation marks.png

    single quotation marks.png
  4. 如果想显示一些特殊字符($、空格、!等),在字符前面加上用转义字符
  5. 有些时候,变量的值可能来源于一些命令,这时你可以使用反单引号`命令`$(命令),例如:
    使用反单引号`命令`的方式

    get information from comand 1.png

    get information from comand 1.png

    使用$(命令)的方式

    get information from comand 2.png

    get information from comand 2.png
  6. 如果变量想增加变量的值,可以使用$variable累加

    append variable value.png

    append variable value.png
  7. 如果变量需要在其他子进程使用,用export关键字来设置变量为环境变量

    export VARIABLE
  8. 系统环境变量一般都是字母全部大写,例如:PATHHOMESHELL
  9. 如果想取消设置变量的值,使用unset variable命令。注意,变量之前是没有符号$

    unset variable.png

    unset variable.png

环境配置文件

之前那些设置的环境变量,一旦退出系统后,就不能再次使用,如果想再次使用,必须重新再设置才行。如果想就算退出系统,也能重新使用自定义的环境变量,那怎么办呢?

不用怕,系统提供一些环境配置文件:/etc/profile~/.bash_profile/etc/profile是系统整体的设置,每个用户共享,最好不要修改;而~/.bash_profile属于单个用户的设置,每个用户设置后,互不影响和共享。但因为我使用oh my zsh,之前~/.bash_profile设置一些配置都不生效了,但它提供一个环境配置文件.zshrc,所以如果想设置环境变量TEST,只需将export TEST=test添加.zshrc即可。

export variable in zshrc file.png

export variable in zshrc file.png

但在.zshrc文件设置好环境变量TEST后,echo $TEST为空,原因是还没使用source命令来读取环境配置文件。使用source .zshrc命令之后,设置环境变量TEST生效了

source command.png

source command.png

数据重定向

含义

当输入命令行时,一般都有输入参数(standard input),而命令行处理完之后,一般都有输出结果,结果有可能成功(standard output),也有可能失败(standard error),而这些结果一般都会输出到屏幕上,如果你想控制结果输出到文件或以文件作为输入的话,你需要了解数据重定向的分类和符号操作。

Redirection.png

Redirection.png

分类

数据重定向主要分为三类:

  • stdin,表示标准输入,代码为0,使用<<<操作符
    符号<表示以文件内容作为输入
    符号<<表示输入时的结束符号
  • stdout,表示标准输出,代码为1,使用>>>操作符
    符号>表示以覆盖的方式将正确的数据输出到指定文件中
    符号>>表示以追加的方式将正确的数据输出到指定文件中
  • stderr,表示标准错误输出,代码为2,使用2>2>>操作符
    符号2>表示以覆盖的方式将错误的数据输出到指定文件中
    符号2>>表示以追加的方式将错误的数据输出到指定文件中

使用

stdout

当你输入ls命令,屏幕会显示当前目录有哪些文件和目录;而当你使用符号>时,输出结果将重定向到dir.txt文件,而不显示在屏幕上

stdin demo.png

stdin demo.png

而符号>与符号>>有什么区别呢?>表示当文件存在时,将文件内容清空,然后stdout结果存放到文件中。而>>表示当文件存在时,文件内容并没有清空,而是将stdout结果追加到文件尾部。

当你再次输入命令ls > dir.txt时,文件内容并没有改变,因为之前文件内容被清空,然后stdout结果存放在dir.txt文件

stdin demo 1.png

stdin demo 1.png

而你这次使用符号ls >> dir.txt的话,文件内容被追加到dir.txt文件

stdin demo 2.png

stdin demo 2.png
stderr

这次我输入命令ls test显示一个不存在的文件,会显示错误信息。然后将错误信息输出到文件error.txt

stderr demo 1.png

stderr demo 1.png

如果你想追加错误信息,可以使用2>>符号

stderr demo 2.png

stderr demo 2.png
stdout & stderr
  • 将stdout和stderr分离:>2>符号
    输入ls README.md test,在屏幕显示既有正确信息,也有错误信息,如果想将正确信息和错误信息分离到不同文件,你可以同时使用>2>符号

    seperate stdout & stderr.png

    seperate stdout & stderr.png
  • 将stdout和stderr合并:&>符号
    如果你想将正确信息和错误信息合并,且输出到同一个文件,可以使用&>符号

    combine stdout & stderr.png

    combine stdout & stderr.png
stdin

一般输入一些简单的数据的方式都是通过键盘,但是如果要输入大量的数据,最好还是通过文件的方式。举一个简单例子:
首先输入cat > test命令之后,你就可以输入内容,那些内容最终会存放在test文件

stdin demo 1.png

stdin demo 1.png

但如果有大量数据从一个文件导入到test文件时,此时需要用到<符号

stdin demo 2.png

stdin demo 2.png

还一个符号<<需要解释,符号<<表示输入时的结束符号。输入cat > test << "eof"命令之后,你就可以输入内容,那些内容最终会存放在test文件,输入完内容后可以输入eof来结束输入

stdin demo 3.png

stdin demo 3.png

管道

在Unix设计哲学中,有一个重要设计原则--KISS(Keep it Simple, Stupid),大概意思就是只关注如何做好一件事,并把它做到极致。每个程序都有各自的功能,那么有没有一样东西将不同功能的程序互相连通,自由组合成更为强大的宏工具呢?此时,管道出现了,它能够让程序实现了高内聚,低耦合

How Pipe works.png

How Pipe works.png

如果我想查看文件是否存在某个关键字,此时我可以使用管道

Pipe Demo.png

Pipe Demo.png

命令cat README.md | grep 'pod'的处理过程分为两步:

  1. cat README.md查看文件内容
  2. 然后将cat README.md输出的内容作为grep 'pod'命令的输入,再进行处理。

上面一个很关键的符号|,就是管道,它能够将前一个命令处理完的stdout作为下一条命令stdin

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

Linux基础知识:shell基础命令-演道网

注:实验系统为Red Hat Enterprise Linux Server release 7.1 (Maipo)

1.什么是shell

​百度:shell俗称壳(区别于核),是指提供使用者使用界面的软件(命令解析器)。
李哥:shell是内核的“保镖”。

 [kiosk@foundation0 Desktop]$ gnome-terminal     ##用命令行开启一个shell

​  kiosk    ​##开启shell的用户
​  @    ​   ##分隔符
  foundation0  ##机的短名称,表示shell开启在那台主机里
​  Desktop    ​#​#表示你在系统的什么位置
​  $    ​   ​##身份提示符中的普通用户,超级用户的提示符为:#

2.切换用户

 ​[kiosk@foundation0 Desktop]$ su - 用户名
 有“-”代表切换用户并且切换环境

3.虚拟控制台

  ​Ctrl + Alt + F2 - F6
​  Ctrl + Alt + F1 | F7

4.Shell中如何使用命令

<1>命令一定要在提示符之后输入
<2>命令的输入方式
    命令  参数  目标
    参数是命令功能的指定
    -参数 ####单词的缩写
    --参数    ####单词的全拼
<3>帮助
    命令  --help
    【内容】    ###内容选加
    <内容>    ###内容必加
    内容...   ###内容个数任意
<4> ctrl +c ###撤销未执行的命令 

5.系统初始化

关机  poweroff        |   init    0   |   shutdown -h     now
重启  reboot          |   init    6   |   shutdown -r     now

6.简单命令

<1>date

date 月月天天时时分分.秒秒 ##更改时间
<2>passwd
passwd username ##更改用户密码(只有超级用户可以)
passwd ##普通用户更改自己的密码
普通用户只能修改自己的密码,并且必须知道自己原始密码,修改密码必须大于8位, 不能与原始密码字符重复
passwd -l username ##冻结普通用户
passwd -u username ##解冻普通用户
这里写图片描述
<3>file ##查看文件什么类型
这里写图片描述
<4>cat ##查看文件所有内容到文件的最后
这里写图片描述
<5>less ##查看文件所有内容从文件的开始
按Q退出
<6>head -数字 文件名称 ##文件的前几行内容
这里写图片描述
<7>tail -数字 文件名称 ##文件的后几行
这里写图片描述
<8>wc -l ##行数
-c ##字节数
-m ##字符数
-w ##单词数
-L ##显示最长行的长度
这里写图片描述
<9>Tab
补齐系统中存在的文件名称,命令,和命令参数
<10>!数字 ###执行第多少条命令
!关键字 ###执行最近一条以关键字开头的命令
ctrl+R+关键字 ###调出最近一条含有关键字的命令
上下键 ###从最后一条命令开始向前查看或者向后查看
history ###查看历史
history -c ###清除历史
<11>快捷键
+ a 光标移动到行首
+ e 光标移动到行尾
+ u 光标所在位置删除到行首
+ k 光标所在位置删除到行尾
+ r 调出最近一条含有关键字的命令
+ 左|右 光标移动以单词为单位
+ c 撤销以输入的命令
+ d 关闭当前环境
+ shift + t ##在现有shell中重新打开一个table
+ shift + pageup|pagedown 切换table
+ alt + l 锁屏
+ alt +上|下 切换工作界面
+ alt + f1|f7 进入图形界面
+ alt + f2-f6 进入虚拟控制台

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

Linux shell数组

引言

  在Linux平台上工作,经常需要我们使用shell来编写一些有用、有意义的脚本程序,有时我们会经常使用shell数组。那么,shell中的数组是怎么表现的呢,又是怎么定义的呢?接下来我们逐一的进行讲解,shell中的数组。

数组的定义

  何为数组?学过计算机编程语言的同学都知道,数组的特性就是一组数据类型相同的集合(不包括有一些编程语言提出来的关联数组的概念)。那么shell中数组是怎么定义的呢,我们来看两种数据类型:一是数值类型,二是字符串类型;虽然shell本身是弱类型的,但也可以这么区分。

  数值类型的数组:一对括号表示数组,数组中元素之间使用“空格”来隔开。

  举个列子: 

  arr_number=(1 2 3 4 5);

  字符串类型数组:同样,使用一对括号表示数组,其中数组中的元素使用双引号或者单引号包含,同样使用“空格”来隔开。

  arr_string=(“abc” “edf” “sss”); 或者 arr_string=(‘abc’ ‘edf’ ‘sss’);

数组的操作

  我们使用数值类型数组arr_number=(1 2 3 4 5)做为源数组进行相关的讲解:获取数组长度,读取某个下标的值,对某个下标赋值,删除、分配和替换以及遍历。提一个知识点,我们在shell里面想获取某个变量的值,使用$符开头,如:$a或者${a}即可。

  获取数组长度

  arr_length=${#arr_number[*]}或${#arr_number[@]}均可,即形式:${#数组名[@/*]} 可得到数组的长度。

  读取某个下标的值

  arr_index2=${arr_number[2]},即形式:${数组名[下标]}

  对某个下标赋值

  这里需要提出两个问题:

    第一个问题是如果该下标元素已经存在,会怎么样?

    答:会修改该下标的值为新的指定值。

    例如:arr_number[2]=100,数组被修改为(1 2 100 4 5)

    第二个问题是如果指定的下标已经超过当前数组的大小,如上述的arr_number的大小为5,指定下标为10或者11或者大于5的任意值会如何?

    答:新赋的值被追加到数组的尾部。

    例如:arr_number[13]=13,数组被修改为(1 2 100 4 5 13)

  删除操作

    清除某个元素:unset arr_number[1],这里清除下标为1的数组;

    清空整个数组:unset arr_number;

  分片访问

    分片访问形式为:${数组名[@或*]:开始下标:结束下标},注意,不包括结束下标元素的值。

    例如:${arr_number[@]:1:4},这里分片访问开始下标为1到结束下标为4的值结果输出为新数组,但不包括下标为4的值。

  模式替换

    形式为:${数组名[@或*]/模式/新值}

    例如:${arr_number[@]/2/98}

  数组的遍历

    数组遍历我们使用for语句来演示:

    for v in ${arr_number[@]}; done

      echo $v;

    done

结束语

  通过上述,我们讲解了shell中数组的定义,已经对数组的相关操作有获取长度,读取某下标值,对某个下标赋值,删除、分配和替换以及遍历。通过上述的讲解,希望能够给与读者在Linux平台中使用shell一些帮助,感谢读者耐心的阅读。

linux 命令sed 使用详解

Linux下批量替换多个文件中的字符串的简单方法。用sed命令可以批量替换多个文件中的字符串。

命令如下:sed -i “s/原字符串/新字符串/g” `grep 原字符串 -rl 所在目录`

例如:我要把 charset=gb2312 替换为 charset=UTF-8,执行命令:sed -i “s/charset=gb2312/charset=UTF-8/g” ‘grep charset=gb2312 -rl /www’ 即可。

解释一下:

-i 表示inplace edit,就地修改文件。

-r 表示搜索子目录

-l 表示输出匹配的文件名

这个命令组合很强大,要注意备份文件。

关于 sed 的更多说明:

1. sed ‘y/1234567890/ABCDEFGHIJ/’ test_sed

test_sed的内容是:

1234567890

2345678901

3456789012

4567890123

执行后,test_sed的内容是:

ABCDEFGHIJ

BCDEFGHIJA

CDEFGHIJAB

DEFGHIJABC

注意变换关系是按两个list的位置对应变换

2. 替换每行所有匹配

sed ‘s/01/Ab/g’ test_sed

1234567890

23456789Ab

3456789Ab2

456789Ab23

注意:第一行的0,1没有分别替换为A,b

删除:d命令

$ sed ‘2d’ example—–删除example文件的第二行。

$ sed ‘2,$d’ example—–删除example文件的第二行到末尾所有行。

$ sed ‘$d’ example—–删除example文件的最后一行。

$ sed ‘/test/’d example—–删除example文件所有包含test的行。

替换:s命令

$ sed ‘s/test/mytest/g’ example—–在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。

$ sed -n ‘s/^test/mytest/p’ example—–(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。

$ sed ‘s/^192.168.0.1/&localhost/’example—–&符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加localhost,变成192.168.0.1localhost。

$ sed -n ‘s/\(love\)able/\1rs/p’ example—–love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。

$ sed ‘s#10#100#g’ example—–不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。

选定行的范围:逗号

$ sed -n ‘/test/,/check/p’ example—–所有在模板test和check所确定的范围内的行都被打印。

$ sed -n ‘5,/^test/p’ example—–打印从第五行开始到第一个包含以test开始的行之间的所有行。

$ sed ‘/test/,/check/s/$/sed test/’ example—–对于模板test和west之间的行,每行的末尾用字符串sed test替换。

多点编辑:e命令

$ sed -e ‘1,5d’ -e ‘s/test/check/’example—–(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。

$ sed –expression=’s/test/check/’ –expression=’/love/d’ example—–一个比-e更好的命令是–expression。它能给sed表达式赋值。

从文件读入:r命令

$ sed ‘/test/r file’ example—–file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面。

写入文件:w命令

$ sed -n ‘/test/w file’ example—–在example中所有包含test的行都被写入file里。

追加命令:a命令

$ sed ‘/^test/a\\—>this is a example’ example<—–‘this is a example’被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。

插入:i命令

$ sed ‘/test/i\\

new line

————————-‘ example

如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。

下一个:n命令

$ sed ‘/test/{ n; s/aa/bb/; }’ example—–如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。

变形:y命令

$ sed ‘1,10y/abcde/ABCDE/’ example—–把1–10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令。

退出:q命令

$ sed ’10q’ example—–打印完第10行后,退出sed。

保持和获取:h命令和G命令

$ sed -e ‘/test/h’ -e ‘$Gexample—–在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。

保持和互换:h命令和x命令

$ sed -e ‘/test/h’ -e ‘/check/x’ example —–互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。

 

linux shell数据重定向(输入重定向与输出重定向)详细分析

引言

在了解重定向之前,我们先来看看linux 的文件描述符。

linux文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作。 用户可以自定义文件描述符范围是:3-num,这个最大数字,跟用户的:ulimit –n 定义数字有关系,不能超过最大值。

linux启动后,会默认打开3个文件描述符,分别是:标准输入standard input 0,标准输出standard output 1,标准错误输出:error output 2

以后打开文件后。新增文件绑定描述符 可以依次增加。 一条shell命令执行,都会继承父进程的文件描述符。因此,所有运行的shell命令,都会有默认3个文件描述符。

对于任何一条linux 命令执行,它会是这样一个过程:

一个命令执行了:

先有一个输入:输入可以从键盘,也可以从文件得到

命令执行完成:成功了,会把成功结果输出到屏幕:standard output默认是屏幕

命令执行有错误:会把错误也输出到屏幕上面:standard error默认也是指的屏幕

文件输入输出由追踪为一个给定的进程所有打开文件的整数句柄来完成。这些数字值就是文件描述符。最为人们所知的文件米描述符是 stdin, stdout 和 stderr,文件描述符的数字分别是0,1和2。这些数字和各自的设备是保留的。一个命令执行前,先会准备好所有输入输出,默认分别绑定(stdin,stdout,stderr),如果这个时候出现错误,命令将终止,不会执行。命令解析过程,可以参考:Linux Shell 通配符、元字符、转义符使用实例介绍

这些默认的输出,输入都是linux系统内定的,我们在使用过程中,有时候并不希望执行结果输出到屏幕。我想输出到文件或其它设备。这个时候我们就需要进行输出重定向了。

linux shell下常用输入输出操作符是:

  1. 标准输入 (stdin) :代码为 0 ,使用 < 或 << ; /dev/stdin -> /proc/self/fd/0 0代表:/dev/stdin
  2. 标准输出 (stdout):代码为 1 ,使用 > 或 >> ; /dev/stdout -> /proc/self/fd/1 1代表:/dev/stdout
  3. 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ; /dev/stderr -> /proc/self/fd/2 2代表:/dev/stderr

输出重定向:

格式:

command-line1 [1-n] > file或文件操作符或设备
上面命令意思是:将一条命令执行结果(标准输出,或者错误输出,本来都要打印到屏幕上面的) 重定向其它输出设备(文件,打开文件操作符,或打印机等等)1,2分别是标准输出,错误输出。
实例:

#显示当前目录文件 test.sh test1.sh test1.sh实际不存在
[chengmo@centos5 shell]$ ls test.sh test1.sh
ls: test1.sh: 没有这个文件和目录
test.sh
 
#正确输出与错误输出都显示在屏幕了,现在需要把正确输出写入suc.txt
# 1>可以省略,不写,默认所至标准输出
[chengmo@centos5 shell]$ ls test.sh test1.sh 1>suc.txt
ls: test1.sh: 没有这个文件和目录
[chengmo@centos5 shell]$ cat suc.txt
test.sh
 
#把错误输出,不输出到屏幕,输出到err.txt
[chengmo@centos5 shell]$ ls test.sh test1.sh 1>suc.txt 2>err.txt
[chengmo@centos5 shell]$ cat suc.txt err.txt
test.sh
ls: test1.sh: 没有这个文件和目录
#继续追加把输出写入suc.txt err.txt  “>>”追加操作符
[chengmo@centos5 shell]$ ls test.sh test1.sh 1>>suc.txt 2>>err.txt
 
#将错误输出信息关闭掉
[chengmo@centos5 shell]$ ls test.sh test1.sh 2>&-
test.sh
[chengmo@centos5 shell]$ ls test.sh test1.sh 2>/dev/null
test.sh
#&[n] 代表是已经存在的文件描述符,&1 代表输出 &2代表错误输出 &-代表关闭与它绑定的描述符
#/dev/null 这个设备,是linux 中黑洞设备,什么信息只要输出给这个设备,都会给吃掉
 
#关闭所有输出
[chengmo@centos5 shell]$ ls test.sh test1.sh  1>&- 2>&-
#关闭 1 ,2 文件描述符
[chengmo@centos5 shell]$ ls test.sh test1.sh  2>/dev/null 1>/dev/null
#将1,2 输出转发给/dev/null设备
[chengmo@centos5 shell]$ ls test.sh test1.sh >/dev/null 2>&1
#将错误输出2 绑定给 正确输出 1,然后将 正确输出 发送给 /dev/null设备  这种常用
<p>[chengmo@centos5 shell]$ ls test.sh test1.sh &>/dev/null
#& 代表标准输出 ,错误输出 将所有标准输出与错误输出 输入到/dev/null文件
</p>

注意:
1、shell遇到”>”操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件。不存在直接创建。 无论左边命令执行是否成功。右边文件都会变为空。
2、“>>”操作符,判断右边文件,如果不存在,先创建。以添加方式打开文件,会分配一个文件描述符[不特别指定,默认为1,2]然后,与左边的标准输出(1)或错误输出(2) 绑定。
3、当命令:执行完,绑定文件的描述符也自动失效。0,1,2又会空闲。
4、一条命令启动,命令的输入,正确输出,错误输出,默认分别绑定0,1,2文件描述符。
5、一条命令在执行前,先会检查输出是否正确,如果输出设备错误,将不会进行命令执行

输入重定向

格式:

command-line [n] <file或文件描述符&设备
将然有,命令默认从键盘获得的输入,改成从文件,或者其它打开文件以及设备输入。执行这个命令,将标准输入0,与文件或设备绑定。将由它进行输入。
实例:

testing
cat file test
#这里按下 [ctrl]+d 离开
#从标准输入【键盘】获得数据,然后输出给catfile文件
 
[chengmo@centos5 shell]$ cat>catfile <test.sh
#cat 从test.sh 获得输入数据,然后输出给文件catfile
 
 
[chengmo@centos5 shell]$ cat>catfile <<eof
test a file
test!
eof
 
#<< 这个连续两个小符号, 他代表的是『结束的输入字符』的意思。这样当空行输入eof字符,输入自动结束,不用ctrl+D

exec绑定重定向

格式:

exec 文件描述符[n] <或> file或文件描述符或设备
在上面讲的输入,输出重定向 将输入,输出绑定文件或设备后。只对当前那条指令是有效的。如果需要在绑定之后,接下来的所有命令都支持的话。就需要用exec命令
实例:

#将标准输出与fd 6绑定
 
[chengmo@centos5 shell]$ ls  /proc/self/fd/ 
0  1  2  3  6
#出现文件描述符6
 
[chengmo@centos5 shell]$ exec 1>suc.txt
#将接下来所有命令标准输出,绑定到suc.txt文件(输出到该文件)
 
[chengmo@centos5 shell]$ ls -al
#执行命令,发现什么都不返回了,因为标准输出已经输出到suc.txt文件了
 
[chengmo@centos5 shell]$ exec 1>&6
#恢复标准输出
 
 
[chengmo@centos5 shell]$ exec 6>&-
#关闭fd 6描述符
 
[chengmo@centos5 ~]$ ls /proc/self/fd/
0  1  2  3

说明:使用前先将标准输入保存到文件描述符6,这里说明下,文件描述符默认会打开0,1,2 还可以使用自定义描述符 。然后对标准输出绑定到文件,接下来所有输出都会发生到文件。 使用完后,恢复标准的输出,关闭打开文件描述符6。
有趣事情:
可能有朋友会这样用:exec 1>suc.txt ,接下来所有输出都绑定到suc.txt 文件,那么怎么样恢复原来的呢? 试试你就会发现问题所在……

复杂一点实例

exec 3<>test.sh;
#打开test.sh可读写操作,与文件描述符3绑定
 
while read line<&3
 do
    echo $line;
done
#循环读取文件描述符3(读取的是test.sh内容)
exec 3>&-
exec 3<&-
#关闭文件的,输入,输出绑定

总结下:

学习就要总结,总结才可以提高了。哈哈!
估计还有一些朋友是头晕晕的。怎么linux的重定向这么复杂呢,又是文件打开描述符又是读,还有些,还有默认标准输入输出。
其实,总结一下,重定向应用通常就以下两点:

1、重新设置命令的默认输入,输出,指向到自己文件(文件,文件描述符,设备其实都是文件,因为linux就是基于设备也是文件,描述符也指向是文件,哈哈)
2、扩展自己新的描述符,对文件进行读写操作

Ubuntu下进行Shell脚本编程中[]的问题

按照《鸟哥私房菜些》的shell编程例子,但是却出现莫名其妙的问题。
如,文件名为sh06.sh:
#!/bin/bash
#Program:
#       This program will show the user’s choice
#History:
#2010/08/01  cnhjq First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p “Please input (Y/N): ”  yn
[ “$yn” == “Y” -o “$yn” == “y” ] && echo “OK,continue.” && exit 0
[ “$yn” == “N” -o “$yn” == “n” ] && echo “oh,interrupt!” && exit 0
echo “I don’t know what is you choice” && exit 0

执行的时候,总是发现提示  [: 10: y: unexpected operator
在终端下按照shell里的命令直接按行输入,居然成功了,不禁再一次感叹了下问题的诡异。

最后在网上找到了答案:
第一种:
因为Ubuntu默认的sh是连接到dash的,又因为dash跟bash的不兼容所以出错了。执行时可以把sh换成bash 文件名.sh来执行(如bash sh06.sh)。成功。
这里需要注意的是dash是什么!问baidu或者google!
修改sh默认连接到bash的一种方法:
sudo dpkg-reconfigure dash
或者这样应该也是可以的

Shell脚本之awk文本编辑器语法

AWK  ——是一种用于处理文本的编程语言工具。
    英文原义:Aho、Weinberger、Kernighan
    中文释义:三位创造者Aho、Weinberger和Kernighan统称

    AWK 在很多方面类似于 shell 编程语言,尽管 AWK 具有完全属于其本身的语法。最初创造 AWK 时,其目的是用于文本处理,并且这种语言的基础是,只要在输入数据中有模式匹配,就执行一系列指令。该实用工具扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行。

    awk 之所以成为一种优秀的程序设计语言的原因之一是内置函数的使用,awk定义并支持了一系列的内置函数,由于这些函数的使用,使得awk提供的功能更为完善和强大。

常用语法:
    awk    [options]    ‘commands’        testfiles
   
options选项
    -F    定义字段分隔符,默认分隔符为连续空格或制表符
        用$1,$2,$3等顺序表示files中每行以间隔符号分隔的各列不同域
    -v    定义变更并赋值,也可以借用次方式从shell变量中引入变量
使用示例:
[root@localhost test]# awk -F”:” ‘{print $1,$7}’ testfile
        以冒号作为分隔符,打印第1和第7个字段
[root@localhost test]# awk -F”[:/]” ‘{print $1,$7}’ testfile
        以冒号或斜杠 / 作为分隔符,打印第1第7个字段
[root@localhost test]# awk -F”:/” ‘{print $1,$7}’ testfile
        以冒号加斜杠 “:/”整体作为分隔符
       
———————————————————–   
command
    读前处理    行处理        读后处理
        1、读前处理    BEGIN{awk_cmd1;awk_cmd2;}
        2、行处理:定址    命令
        定址方法:正则,变量,比较,关系运算
                正则需要用 / / 包裹起来
        常用正则:
            ^    行首                $    行尾
              .    除了换行符以外的任意单个字符
              *    前导字符的零个或多个
              .*    所有字符
              []    字符组内的任一字符
              [^]    对字符组内的每个字符取反(不匹配字符组内的每个字符)
              ^[^]    非字符组内的字符开头的行
              [a-z] 小写字母
              [A-Z] 大写字母
              [a-Z] 小写和大写字母
              [0-9] 数字
              \<    单词头,以空格或特殊字符做分隔,连续的字符串被当做单词
              \>    单词尾

        扩展正则
              ?        前导字符零个或一个
              +        前导字符一个或多个
              abc|def        abc或def
              a(bc|de)f        abcf 或 adef
              x\{m\}          x出现m次
              x\{m,\}          x出现m次至多次(至少m次)
              x\{m,n\}        x出现m次至n次

        NR变量定址,NR 表示AWK读入的行数
        FNR表示读入行所在文件中的行数
       
        逻辑运算——可直接引用域进行运算
            ==    >=    <=    !=    >    <    ~    !~
            如:# awk ‘NR==1 {print}’  /etc/passwd
                    root:x:0:0:root:/root:/bin/bash
                           
        命令    如:{print $1,$2}
       
    3、读后处理
        END {awk_cmd1;awk_cmd2;}

—————————————————————
AWk的变量
    NR    AWK处理的总行数
    FNR  AWK处理的当前文件的行数,非全部
    FS    字段分隔符,默认为连续空格或制表符,可以使用多个不同的符号做分隔符,也可在options出使用  -F[:/]    指定分隔符
    OFS  输出字符的分隔符 默认是空格
            如:# awk -F: ‘OFS=”***” {print $1,$2}’ /etc/passwd
                      root***x
    NF    当前读入行的字段个数
    ORS  输出行的分隔符,默认是换行
        # awk -F: ‘ORS=”***” {print $1,$2}’ /etc/passwd
        root x***bin x***
    FILENAME    当前文件名

更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2013-11/92787p2.htm

相关阅读:

sed与awk常用功能 http://www.linuxidc.com/Linux/2013-06/86099.htm

Linux下shell编程常用grep\awk\sed语法 http://www.linuxidc.com/Linux/2013-07/87047.htm

Linux下Shell编程——awk编程 http://www.linuxidc.com/Linux/2013-06/85527.htm

文本处理工具awk详解 http://www.linuxidc.

Linux Shell 通配符、元字符、转义符使用实例介绍

通配符是由shell处理的(不是由所涉及到命令语句处理的,其实我们在shell各个命令中也没有发现有这些通配符介绍), 它只会出现在 命令的“参数”里(它不用在 命令名称里, 也不用在 操作符上)。当shell在“参数”中遇到了通配符时,shell会将其当作路径或文件名去在磁盘上搜寻可能的匹配:若符合要求的匹配存在,则进行代换(路径扩展);否则就将该通配符作为一个普通字符传递给“命令”,然后再由命令进行处理。总之,通配符 实际上就是一种shell实现的路径扩展功能。在 通配符被处理后, shell会先完成该命令的重组,然后再继续处理重组后的命令,直至执行该命令。

 

我们回过头分析上面命令吧:在第2个命令中,*.txt 实际shell搜索文件,找到了符合条件的文件,命令会变成:ls a.txt b.txt ,实际在执行ls 时候传给它的是a.txt b.txt .

 

而命令3,d*.txt 由于当前目录下面没有这样的文件或目录,直接将”d*.txt” 作为ls 参数,传给了 ls .这个时候”*” 只是一个普通的 ls 参数而已,已经失去了它通配意义。 由于找不到文件,所以会出现:无法访问提示!

了解了shell通配符,我们现在看下,shell常见通配符有那一些了。

shell常见通配符:

字符 含义 实例
* 匹配 0 或多个字符 a*b  a与b之间可以有任意长度的任意字符, 也可以一个也没有, 如aabcb, axyzb, a012b, ab。
? 匹配任意一个字符 a?b  a与b之间必须也只能有一个字符, 可以是任意字符, 如aab, abb, acb, a0b。
[list]  匹配 list 中的任意单一字符 a[xyz]b   a与b之间必须也只能有一个字符, 但只能是 x 或 y 或 z, 如: axb, ayb, azb。
[!list]  匹配 除list 中的任意单一字符 a[!0-9]b  a与b之间必须也只能有一个字符, 但不能是阿拉伯数字, 如axb, aab, a-b。
[c1-c2] 匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z] a[0-9]b  0与9之间必须也只能有一个字符 如a0b, a1b… a9b。
{string1,string2,…} 匹配 sring1 或 string2 (或更多)其一字符串 a{abc,xyz,123}b    a与b之间只能是abc或xyz或123这三个字符串之一。

 

需要说明的是:通配符看起来有点象正则表达式语句,但是它与正则表达式不同的,不能相互混淆。把通配符理解为shell 特殊代号字符就可。而且涉及的只有,*,? [] ,{} 这几种。

linux shell 时间运算以及时间差计算方法

最近一段时间,在处理Shell 脚本时候,遇到时间的处理问题。 时间的加减,以及时间差的计算。

 

1。 时间加减

 

这里处理方法,是将基础的时间转变为时间戳,然后,需要增加或者改变时间,变成 秒。

 

如:1990-01-01 01:01:01  加上 1小时 20分

处理方法:

a.将基础时间转为时间戳

time1=$(date +%s -d ‘1990-01-01 01:01:01’)

echo $time1

631126861 【时间戳】

 

b.将增加时间变成秒

[root@localhost ~]# time2=$((1*60*60+20*60))
[root@localhost ~]# echo $time2

4800

 

c.两个时间相加,计算出结果时间

time1=$(($time1+$time2))

time1=$(date +%Y-%m-%d\ %H:%M:%S -d “1970-01-01 UTC $time1 seconds”);

echo $time1

1990-01-01 02:21:01

 

2。时间差计算方法

 

如:2010-01-01 与 2009-01-01 11:11:11 时间差

原理:同样转成时间戳,然后计算天,时,分,秒

 

time1=$(($(date +%s -d ‘2010-01-01’) – $(date +%s -d ‘2009-01-01 11:11:11’)));

echo time1

 

将time1 / 60 秒,就变成分了。

 

补充说明:

shell 单括号运算符号:

a=$(date);

等同于:a=`date`;

 

双括号运算符:

a=$((1+2));

echo $a;

等同于:

a=`expr 1 + 2`