Shell默认选项himBH的解释

前端之家收集整理的这篇文章主要介绍了Shell默认选项himBH的解释前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

转自:团子的小窝,本文固定链接:Shell 默认选项 himBH 的解释

SegmentFault的问题地址:求大大解释如下shell语句

$echo$-
himBH

1、himBH这个结果又是什么意思?
2、看不懂,求第69行详解。多谢++

foriin/etc/profile.d/*.sh;do
if[-r"$i"];then
if["${-#*i}"!="$-"];then
."$i"
else
."$i">/dev/null2>&1
fi
fidone
@H_@R_301_450@_20@

以下是我的回答:

1. himBH 这个结果又是什么意思?

$-记录着当前设置的shell选项,himBH是默认值,你可以通过 set 命令来设置或者取消一个选项配置。例如:

set-x

这个可以打开 shell 的调试开关,调试 shell 脚本非常有用,这个时候再检查下 $- 变量的值,可以看到多了 x 字符:

[kodango@mac]~
$echo$-
+echohimxBH#-x选项设置的效果
himxBH

回到himBH上,我们来一个一个看这几个默认选项分别影响了 Shell 的哪些行为。

i - interactive

包含这个选项说明当前的 shell 是一个交互式的 shell,何为交互式?你输入命令,shell 解释执行后给你返回结果,我们在 Terminal 下使用的 shell 就是交互式的,所以 $- 会包含 i 字符。如果我们在一个脚本里面 echo $-,结果是不会包含 i 的。关于交互式 Shell,我之前在博客里写过一篇文章专门介绍,有兴趣的可以看看。

H - history expand

history expand 这个很多人都基本上不用,包括我也是。我们知道 Shell 会把我们执行的命令记录下来,可以通过 history 命令查看,每一行是序号 + 执行的命令。在 shell 退出时,会将这些信息保存到~/.bash_history 文件中,当然在启动时也会从该文件中加载,不信删除这个文件再打开一个终端试试。

history expand 就是展开历史列表中的命令,可以通过!感叹号来完成,例如"!!"返回上最近的一个历史命令,"!n"返回第 n 个历史命令,等等,具体可以看 Bash 的 Man手册,这里不多介绍。

多扯一句,在命令行下,不要在双引号号里面用!,这会让 Shell "误以为" 你要执行历史展开:

[kodango@mac]~
$echo"hello,world!"
-bash:!":eventnotfound

关于这一点,我也在简洁的 Bash Programming 技巧续篇的第9条中有提到过,解决方法有两种:使用单引号或者关闭历史展开功能(在脚本里面默认是关闭的):

$echo'hello,world!'
hello,world!

[kodango@mac]~
$set+H

[kodango@mac]~
$echo"hello,world!"
hello,world!

B - brace expansion

Brace expansion 是一个很有用的技巧,我这里简单介绍一个:

[kodango@mac]~
$cp/your/path/to/file{,.bak}

很多时候大家需要备份某个文件时,非常头疼的一点就是要重复输入长长地路径,利用 Brace expansion 就可以轻松搞定。

你可以试试通过set +B关闭这个功能,与前面几个选项不同的是,这个选项在脚本里面也是默认打开的。

m - monitor mode

字面意思是说打开监控模式,Bash 手册上后面还有一句话"Job control is enabled",Job control 是什么?就是说可以控制进程的停止、继续,后台或者前台执行等。

正常情况下,在交互式模式下,该选项默认是打开的,所以再执行一个比较耗时的命令时,你可以按下CTRL+Z让它在后台运行,然后可以用 fg 命令将后台运行的任务恢复到前台执行:

[kodango@mac]~
$sleep10
+sleep10
^Z
[1]+Stoppedsleep10

[kodango@mac]~
$fg
+fg
sleep10

如果关闭这个选项,你就失去了控制 Job 的能力:

[kodango@mac]~
$set+m

[kodango@mac]~
$sleep10
^Z^Z^C

[kodango@mac]~
$fg
-bash:fg:nojobcontrol

Stackoverflow 上相关的问题:Why can't I use job control in a bash script?

h - hashall

这个选项的意思我不是很明白,猜测打开这个选项后,Shell 会将命令所在的路径记录下来,避免每次都要查询

我们要验证下这个猜测,首先在/usr/bin 下创建任意一个可执行的文件

[kodango@mac]~
$echo"testhashall"|sudotee/usr/bin/kodango&&sudochmod+x/usr/bin/kodango

[kodango@mac]~
$kodango
testhashall

[kodango@mac]~
$sudomv/usr/bin/kodango/usr/local/bin/kodango

[kodango@mac]~
$kodango
-bash:/usr/bin/kodango:Nosuchfileordirectory

好吧,果不其然,“缓存”失效了。接下来,我们关闭这个选项:

[kodango@mac]~
$set+m

[kodango@mac]~
$kodango
testhashall

[kodango@mac]~
$whichkodango
/usr/local/bin//kodango

现在工作正常了,不过谁会经常没事瞎移动命令呢?所以这个选项默认都是打开的。

最后,你也可以通过set -o命令来查看当前 shell 的选项配置。

2. 看不懂,求第69行详解。多谢++

${-#*i}翻译过来是说,从左往右看,删除掉 $- 变量的值中第一个 i 字符以及之前的内容。与此相对的,还有${-%i*}的写法,%与#号的意义刚好相反,从右往左看,删除掉 $- 变量的值中最后一个 i 字符以及之后的内容

这种语法学名叫“Parameter Substitution”或者“Parameter Expansion”,这一类下还有其它很多种形式,具体可以 ABS 的这一节

原文链接:https://www.f2er.com/bash/389813.html

猜你在找的Bash相关文章