Linux系统学习笔记:shell环境

Linux系统学习笔记:shell环境
Linux系统中包含强大的shell环境,作为命令解释器。通过shell环境不仅可以和大量的命令行工具进行交互,而且shell还支持脚本编程,以批处理的方式完成更为复杂耗时的工作。BASH是目前绝大多数Linux版本的默认shell解释器。本篇我们以BASH为基础总结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.txt
2012-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.txt
2012-03-08 16:56:00+08:00
$ set +o noclobber
$ date --rfc-3339=seconds > d.txt
$ cat d.txt
2012-03-08 16:56:31+08:00
$ date --rfc-3339=seconds >> d.txt
$ cat d.txt
2012-03-08 16:56:31+08:00
2012-03-08 16:57:14+08:00
$ cat /dev/null > d.txt    # 删除文件内容
$ grep -i alex <<+
> Alex
> Harry
> Nancy
> +
Alex

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

$ cat a
file a
$ cat b
cat: b: No such file or directory
$ cat a b > out          # 重定向标准输出到out
cat: b: No such file or directory
$ cat out
file a
$ cat a b 1> out 2>&1    # 重定向标准输出到out,重定向标准错误输出到标准输出(即out)
$ cat out
file a
cat: b: No such file or directory
$ cat a b 2>&1 1> out    # 重定向标准错误输出到标准输出,重定向标准输出到out
cat: b: No such file or directory
$ cat out
file 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=s
2012-03-09 09:07:17+08:00
$ date --rfc-3339=s           # 等待超过10s
2012-03-09 09:07:32+08:00
$ bg                          # sleep作业仍在,移到后台并运行
[2]+ sleep 10 &
$ jobs                        # 显示作业列表,sleep因为超时而结束
[1]+  Stopped                 cat
[2]-  Done                    sleep 10
$ %1                          # 将作业1移到前台;挂起cat,作业号1
cat
^Z
[1]+  Stopped                 cat
$ bg 1                        # 将作业1移到后台
[1]+ cat &
$ jobs                        # 显示作业列表
[1]+  Stopped                 cat
$ fg                          # 将作业1移到前台;中断cat
cat
^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配置文件中配置它。

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

扩展

{}扩展

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

$ touch a{1,2,3,4,5}.txt
$ ls
a1.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 $n
5 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 fa
fa
$ echo $fa
a1 a2 a3
$ echo ${fa}a
a*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/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值