Linux系统学习笔记:shell环境

来源:互联网 发布:php laravel 入门教程 编辑:程序博客网 时间:2024/06/15 13:08
Linux系统学习笔记:shell环境
Linux系统中包含强大的shell环境,作为命令解释器。通过shell环境不仅可以和大量的命令行工具进行交互,而且shell还支持脚本编程,以批处理的方式完成更为复杂耗时的工作。BASH是目前绝大多数Linux版本的默认shell解释器。本篇我们以BASH为基础总结shell环境。

Contents

  • shell环境
  • 重定向
  • 管道
  • 后台运行
  • 目录栈
  • 命令历史
  • Readline库
  • 别名
  • 扩展
    • {}扩展
    • ~扩展
    • 算术扩展
    • 命令替换
    • 路径扩展
  • 变量
    • 关键字变量
  • 函数
  • shell特性

shell环境

在文本界面或者图形界面的终端模拟窗口中,shell作为命令解释器运行,称为shell环境。有多个版本的shell,通常BASH用的较多。

BASH通过 /etc/profile 文件进行全局配置。登录时,会查找并执行 ~/.bash_profile 、 ~/.bash_login、 ~/.profile ,注销时执行 ~/.bash_logout 。非登录还会执行 /etc/bashrc 和 ~/.bashrc 文件。非交互的BASH不执行这些初始化文件中的命令,只继承它们设置的变量,并且执行 BASH_ENV 环境变量指定的文件中的命令。

一般需要修改默认的环境变量时,在profile文件( ~/.bash_profile 、 ~/.profile 、 /etc/profile )中修改。而命令如命令别名在rc文件( ~/.bashrc 、 /etc/bash.bashrc )中修改。

shell命令在键入回车之后执行,在此之前可以修改。

下面是shell环境中一些键的作用:

Backspace  Delete  ^H删除字符^W删除单词^U删除行^C中断^Z挂起^D退出当前用户登录

shell中输入的命令的语法是:

cmd [arg] ... [arg]

通常开始为命令名,后面接可选的参数。以 - 或 -- 开头的参数也称为选项,一般放在普通的参数之前,由命令解释, - 开头的选项通常可以合并。可以使用 -- 来表示后面的参数不解释为选项。

shell在 PATH 环境变量指定的路径下查找用户拥有执行权限的程序。

shell中的特殊字符包括:

`  !  #  $  %  ^  &  *  +  ~  \  |  ;  '  "  /  ?  <  >  (  )  [  ]  {  }

在特殊字符前加上 \ 可以对特殊字符进行转义,也可以通过使用单引号将它们括起来。输入控制字符可以先按 ^V 。

; 号可以分隔多条命令,但不立即执行它们。对于单条命令过长时,可以使用 \ 换到下一行继续输入。 ()可以对命令分组,shell为每组命令创建一个子shell,把它们作为一个作业。

# 开始行注释。 && 和 || 为逻辑与和逻辑或,连接命令可以做短路判断。 ! 反转命令的退出状态值。

此外, . 在行首时执行命令。

重定向

一个程序的进程会打开3个文件描述符,分别是标准输入(0)、标准输出(1)和标准错误输出(2)。一般情况下,标准输入是键盘,标准输出和标准错误输出是shell输出,可以通过重定向来改变标准输入输出的关联。 < 重定向标准输入( 0< 的简写), > 重定向标准输出( 1> 的简写), 2> 重定向标准错误输出, >> 将标准输出追加到文件, << 将脚本的内容重定向为脚本的输入。

<< 重定向的内容称为Here文档,使用一个或多个符号来界定,开头的界定符必须紧挨 << ,结尾的界定符必须独占一行。

重定向会覆盖已有文件,可以设置 noclobber 来禁止重定向时重写,而 >| 则可以忽略 noclobber 设置。

/dev/null 称为位桶,可以将标准输出重定向到 /dev/null 来抛弃输出的内容。

$ set -o noclobber$ date --rfc-3339=seconds > d.txt$ cat d.txt2012-03-08 16:55:46+08:00$ date --rfc-3339=seconds > d.txt-bash: d.txt: cannot overwrite existing file$ date --rfc-3339=seconds >| d.txt$ cat d.txt2012-03-08 16:56:00+08:00$ set +o noclobber$ date --rfc-3339=seconds > d.txt$ cat d.txt2012-03-08 16:56:31+08:00$ date --rfc-3339=seconds >> d.txt$ cat d.txt2012-03-08 16:56:31+08:002012-03-08 16:57:14+08:00$ cat /dev/null > d.txt    # 删除文件内容$ grep -i alex <<+> Alex> Harry> Nancy> +Alex

可以用 &n 代替重定向到的文件名, n 为文件描述符。重定向到 &- 表示关闭该描述符。

$ cat afile a$ cat bcat: b: No such file or directory$ cat a b > out          # 重定向标准输出到outcat: b: No such file or directory$ cat outfile a$ cat a b 1> out 2>&1    # 重定向标准输出到out,重定向标准错误输出到标准输出(即out)$ cat outfile acat: b: No such file or directory$ cat a b 2>&1 1> out    # 重定向标准错误输出到标准输出,重定向标准输出到outcat: b: No such file or directory$ cat outfile a

管道

shell环境下的管道可以将前一个命令的输出作为后一个命令的输入,管道实际上并不单独处理每条命令,而且不产生中间文件。语法为:

cmd [args] | cmd [args]

管道可以串联,也可以和重定向组合使用。

$ who | tee w.out | grep yeolar    # 还生成了包含全部登录用户的w.out文件yeolar   pts/2        2012-03-08 16:13 (yeolar-pc.local)

tee 命令可以将标准输入复制到标准输出和文件。

后台运行

命令默认在前台运行,在命令执行完毕后将控制权交回shell。可以让命令在后台运行,这样可以不必等待命令执行完毕。命令或管道连接的命令序列称为作业,可以有多个作业在后台运行。同一时间运行多个作业称为多任务特性。

在命令行末尾加上 & 可以使作业在后台运行。shell会给作业分配一个作业编号。 jobs 显示作业的列表。使用 fg 命令(或 % )可以将后台作业移到前台,使用 bg 命令可以将挂起的作业移到后台运行。

$ cat &                       # 后台运行cat,作业号1,PID 2640;挂起sleep,作业号2[1] 2640$ sleep 10^Z[1]-  Stopped                 cat[2]+  Stopped                 sleep 10$ date --rfc-3339=s2012-03-09 09:07:17+08:00$ date --rfc-3339=s           # 等待超过10s2012-03-09 09:07:32+08:00$ bg                          # sleep作业仍在,移到后台并运行[2]+ sleep 10 &$ jobs                        # 显示作业列表,sleep因为超时而结束[1]+  Stopped                 cat[2]-  Done                    sleep 10$ %1                          # 将作业1移到前台;挂起cat,作业号1cat^Z[1]+  Stopped                 cat$ bg 1                        # 将作业1移到后台[1]+ cat &$ jobs                        # 显示作业列表[1]+  Stopped                 cat$ fg                          # 将作业1移到前台;中断catcat^C

目录栈

dirs 命令显示目录栈, pushd 改变目录,并将目录压入目录栈,不加参数时交换栈顶的两个目录, popd将目录从栈中弹出,不加参数时弹出栈顶目录,并改变到该目录。

$ mkdir -p a/b/c$ dirs~$ pushd a/~/a ~$ pushd b/c/           # pwd:~/a~/a/b/c ~/a ~$ pushd                # pwd:~/a/b/c~/a ~/a/b/c ~$ pushd b/             # pwd:~/a~/a/b ~/a ~/a/b/c ~$ pushd +1             # pwd:~/a/b~/a ~/a/b/c ~ ~/a/b$ popd +1              # pwd:~/a~/a ~ ~/a/b$ popd                 # pwd:~/a~ ~/a/b$ popd +1~

命令历史

HISTSIZE 、 HISTFILE 和 HISTFILESIZE 可以设置命令历史的保存数量和文件。

fc 命令可以查看( -l )、编辑(无参数或 -e )、重新执行( -s )命令。

还可以用 ! 引用事件(即命令):

!!执行前一个命令!n执行历史列表编号为n的命令,n为负值时,执行最近第|n|条命令!str执行最近以str开头的命令!?str[?]执行最近包含str的命令,后面的?是可选的!#当前命令已经输入的部分!{event}{}将event和左右文本隔开

命令可以使用字标志符和修饰符进行一些修改和替换等。

Readline库

BASH的命令行编辑是通过Readline库实现的。有vi和emacs两种编辑模式可选。命令行的诸如命令行补全和一些快捷键功能都是源于Readline库。

别名

BASH的另一个很方便的功能是别名,通过 alias 将命令简化。 alias 可以嵌套。一般会在BASH的rc配置文件中配置它。

$ aliasalias ls='ls --color=auto'$ alias ll='ls -l'

扩展

{}扩展

{} 中以 , 分隔开的字符串会扩展成以空格符分开的字符串列表, {} 两端可以有可选的前缀和后缀,它们被加到字符串列表中每个字符串的两端。

$ touch a{1,2,3,4,5}.txt$ lsa1.txt  a2.txt  a3.txt  a4.txt  a5.txt

~扩展

~ 代替 HOME 变量的值。如果 ~ 后面跟一个合法的用户名,那就会替换为该用户的主目录。在目录栈中, ~+为当前工作目录, ~- 为前一个工作目录。

$ echo ~root/root

算术扩展

$((expr)) 会计算 expr 并用结果替代它。BASH中使用整数进行计算。在 $(()) 中变量的引用符 $ 可以省略。 let 命令也计算算术表达式的值,而且可以给它传递多个参数。

$ x=3 y=7; echo $(((x+y)/2))5$ let m=(x+y)/2 n=(x+y)/m; echo $m $n5 2

命令替换

命令替换的语法有两种: $(cmd) 和 `cmd` ,它们用命令的输出替代该命令。

$ ls -l $(find . -name README -print)

路径扩展

对于包含特殊字符的文件名,shell可以生成和已有文件的名字匹配的文件名,这称为路径扩展或通配,特殊字符称为通配符。

? 匹配单个字符, * 匹配0或多个字符, [] 匹配方括号中的任意一个字符,可以用 - 指定字符范围,还可以在字符列表前用 ! 或 ^ 表示不匹配任意一个字符。

$ touch a111 a1 a2 a3 a5 b2 b3 c5$ echo *a1 a111 a2 a3 a5 b2 b3 c5$ echo .*. ..$ echo a*a1 a111 a2 a3 a5$ echo a?a1 a2 a3 a5$ echo a[1-3]a1 a2 a3$ echo a[!1-3]a5$ echo a[^1-3]a5$ echo [a-z]*a1 a111 a2 a3 a5 b2 b3 c5$ echo [a-z]?a1 a2 a3 a5 b2 b3 c5

变量

shell变量以字母(包括 _ )和数字组成,以字母开头。全局变量又称环境变量,通常采用大写形式。使用= 号创建变量, = 两边没有空格。变量值默认以字符串形式保存。在变量名前加上 $ 来引用变量,可以在变量名两边加上 {} 来消除歧义。

赋值语句 = 右侧为空可以将值置空, unset 命令删除变量。

单引号和双引号将内容解释为字符串,单引号会阻止引用。

$ fa=a*$ echo fafa$ echo $faa1 a2 a3$ echo ${fa}aa*a$ echo "$fa"a*$ echo '$fa'$fa

可以使用 declare 或 typeset 设置变量属性,有以下选项:

-a声明数组变量-f声明函数变量-i声明整型变量-r声明只读变量,等价于 readonly-x输出变量(设置为全局变量),等价于 export

如果将选项的前导 - 改为 + ,可以删除特定属性。不带参数时,列出所有特定类或全部的变量。

关键字变量

HOME 变量保存用户主目录, ~ 会被shell展开为 HOME 值。

PATH 指定了shell的搜索路径,搜索路径由 : 分隔的一组路径组成。 export PATH 会使其可被子shell访问。

$ export PATH=$PATH:$HOME:    # 中间的:也可省略

CDPATH 和 PATH 语法类似,它扩展了 cd 命令可进入目录的范围。

PS1 设置用户主提示符, PS2 设置用户次提示符,默认为 > , PS3 设置 select 控制结构的菜单提示符,PS4 设置BASH调试提示符。

IFS 设置分词的分隔符,默认为空白符,通常不需要对其进行修改。

更多的关键字变量可以参考 man bash 手册。

函数

函数也是一种变量,创建函数的语法为:

[function ]name (){    command}

函数将一组命令放在一起,方便了调用。函数名和命令一样,执行函数只需执行函数名即可。

可以把常用的函数放在BASH的profile文件中。

shell特性

可以使用 set -o 和 set +o 开启和关闭shell的特性。BASH的特性参看 man bash 。

链接: http://www.yeolar.com/note/2012/03/07/linux-shell/