#yyds干货盘点# linux命令 shopt

古人学问无遗力,少壮工夫老始成。这篇文章主要讲述#yyds干货盘点# linux命令 shopt相关的知识,希望能为你提供帮助。
shopt 其实很少用到,但是也是有一定作用的。主要就是 shopt命令用于显示和设置shell中的行为选项,通过这些选项以增强shell易用性。




shopt  语法
语法很简单: 
shopt [-psu] [optname …]
其中:
-s:激活指定的shell行为选项;
-u:关闭指定的shell行为选项。
-p: 列出所有可设置的选项.执行shopt 看看都有那些选项 与 系统的默认值




shopt命令可以不带参数,若不带任何参数选项,则可以显示所有可以设置的shell操作选项。[root@master four]# shopt
autocd           off
cdable_vars     off
cdspell         off
checkhash       off
checkjobs       off
checkwinsize     on
cmdhist         on
compat31         off
compat32         off
compat40         off
dirspell         off
dotglob         off
execfail         off
expand_aliases   on
extdebug         off
extglob         on
extquote         on
failglob         off
force_fignore   on
globstar         off
gnu_errfmt       off
histappend       off
histreedit       off
histverify       off
hostcomplete     on
huponexit       off
interactive_comments on
lithist         off
login_shell     on
mailwarn         off
no_empty_cmd_completion off
nocaseglob       off
nocasematch     off
nullglob         off
progcomp         on
promptvars       on
restricted_shell off
shift_verbose   off
sourcepath       on
xpg_echo         off
上面的输出,也就包括了shopt 所支持的所有的参数。




shopt 参数含义说明
上面展示了 shopt 所有的参数。这一大堆参数估计大家看名字难以猜测含义,下面给出这些参数的含义。
选项      含义
cdable_vars :  
        如果给cd内置命令的参数不是一个目录,就假设它是一个变量名,变量的值是将要转换到的目录


cdspell   :
纠正cd命令中目录名的较小拼写错误.检查的错误包括颠倒顺序的字符,遗漏的字符以及重复的字符.如果找到一处需修改之处,正确的路径将打印出,命令将继续.只用于交互式shell


checkhash   :  
      bash在试图执行一个命令前,先在哈希表中寻找,以确定命令是否存在.如果命令不存在,就执行正常的路径搜索


checkwinsize   :
  bash在每个命令后检查窗口大小,如果有必要,就更新LINES和COLUMNS的值


cmdhist   :  
        bash试图将一个多行命令的所有行保存在同一个历史项中.这是的多行命令的重新编辑更方便


dotglob   :
Bash在文件名扩展的结果中包括以点(.)开头的文件名


execfail :
如果一个非交互式shell不能执行指定给exec内置命令作为参数的文件,它不会退出.如果exec失败,一个交互式shell不会退出


expand_aliases :
        别名被扩展.缺省为打开


extglob :
        打开扩展的模式匹配特性(正常的表达式元字符来自Korn shell的文件名扩展)


histappend :
    如果readline正被使用,用户有机会重新编辑一个失败的历史替换


histverify :
如果设置,且readline正被使用,历史替换的结果不会立即传递给shell解释器.而是将结果行装入readline编辑缓冲区中,允许进一步修改


hostcomplete :
          如果设置,且readline正被使用,当正在完成一个包含@的词时bash将试图执行主机名补全.缺省为打开


huponexit   :
          如果设置,当一个交互式登录shell退出时,bash将发送一个SIGHUP(挂起信号)给所有的作业


interactive_comments   :
  在一个交互式shell中.允许以#开头的词以及同一行中其他的字符被忽略.缺省为打开


lithist         :
          如果打开,且cmdhist选项也打开,多行命令讲用嵌入的换行符保存到历史中,而无需在可能的地方用分号来分隔


mailwarn   :
            如果设置,且bash用来检查邮件的文件自从上次检查后已经被访问,将显示消息”The mail in mailfile has been read”


nocaseglob   :
            如果设置,当执行文件名扩展时,bash在不区分大小写的方式下匹配文件名


nullglob:
            如果设置,bash允许没有匹配任何文件的文件名模式扩展成一个空串,而不是他们本身


promptvars :
            如果设置,提示串在被扩展后再进行变量和参量扩展.缺省为打开


restricted_shell   :
            如果shell在受限模式下启动就设置这个选项.该值不能被改变.当执行启动文件时不能复位该选项,允许启动文件发现shell是否受限


shift_verbose   :
              如果该选项设置,当移动计数超出位置参量个数时,shift内置命令将打印一个错误消息


sourcepath   :
              如果设置,source内置命令使用PATH的值来寻找作为参数提供的文件的目录.缺省为打开
source   :
              点(.)的同义词  


shell脚本中 alias 不起作用的问题
默认情况下,  shell 中的 alias 是不会有任何作用的。
[root@localhost meng]# shopt expand_aliases
expand_aliases on
[root@localhost meng]#


但是在  sh 脚本中 执行  shopt expand_aliases, 却打印的是false。 郁闷了,奇怪了。
测试发现,只能把    shopt -s expand_aliases 添加到脚本中去;也是不得已。
但是呢, 这个sh脚本 只能在当前 终端起作用, 新的终端就不行了。 
于是,想到放入启动脚本  ~/.bashrc, 
最终,我的脚本如下:

[root@localhost meng]# cat gc.sh
#!/bin/bash
echo -e"alias t1=\\"echo `date` ++++++\\" " > > ~/.bashrc
# 可以多个...
echo -e"shopt -s expand_aliases" > > ~/.bashrc
#source~/.bashrc
#shopt expand_aliases
# t1 # 直接测试

之后执行./gc.sh 既可以了吗? gc.sh 中的t1 确实有输出,但是直接执行t1 ,还是报错, 重新打开一个 终端执行t1 也是可以的。。
当前终端,修改了~/.bashrc 不会生效,那么就手动执行吧:
  ./gc.sh  & & source  ~/.bashrc
然后就可以直接使用了!


详细说明(转载  )
++++++++++++ 转载  ++++++++++++ 


在非交互式模式下alias扩展功能默认是关闭的,此时仍然可以定义alias别名,但是shell不会将alias别名扩展成对应的命令,而是将alias别名本身当作命令执行,如果shell内置命令和PATH中均没有与alias别名同名的命令,则shell会“抱怨”找不到指定的命令。
如果想使得非交互模式下支持alias扩展, 就要使用shopt expand_aliases. 注意shopt这个命令是shell内置命令,可以控制shell功能选项的开启和关闭,从而控制shell的行为。shopt的使用方式如下:
shopt -s opt_name # Enable (set) opt_name.
shopt -u opt_name # Disable (unset) opt_name.
shopt opt_name # Show current status of opt_name.
测试一下alias在非交互模式的表现和使用shopt的异同:
#!/bin/bash
alias echo_hello=“echo Hello!”
shopt expand_aliases
echo_hello


执行一下:
#> expand_aliases off
#> ./test.sh: line 5: echo_hello: command not found
【#yyds干货盘点# linux命令 shopt】

再次修改  ./test.sh ,在  shopt expand_aliases 前面增加一行  shopt -s expand_aliases , 如下:
shopt -s expand_aliases
shopt expand_aliases
echo_hello
执行一下:
#> ./test.sh
#> expand_aliases on
#> Hello!
另外,alias别名只在当前shell有效,不能被子shell继承,也不能像环境变量一样export。可以把alias别名定义写在.bashrc文件中,这样如果启动交互式的子shell,则子shell会读取.bashrc,从而得到alias别名定义。但是执行shell脚本时,启动的子shell处于非交互式模式,是不会读取.bashrc的。
不过,如果你一定要让执行shell脚本的子shell读取.bashrc的话,可以给shell脚本第一行的解释器加上参数:
#!/bin/bash --login
–login使得执行脚本的子shell成为一个login shell,login shell会读取系统和用户的profile及rc文件,因此用户自定义的.bashrc文件中的内容将在执行脚本的子shell中生效。
还有一个简单的办法让执行脚本的shell读取.bashrc,在脚本中主动source ~/.bashrc即可。
还有一种解决办法是用source命令:
source script.sh
使当前shell读入路径为script.sh的文件并依次执行文件中的所有语句。
那么source和sh去执行脚本有什么不同呢?
sh script.sh 会重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell是新建的,其改变的变量不会被带回父shell,除非使用export。
source script.sh是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。
那么sh script.sh和./script.sh又有什么不同呢?
相同的是它们都是新建一个子shell去执行脚本,不同的是./script.sh要求script.sh必须具有执行权限。
一个简单的alias的例子是:
alias ll=ls -l


————————————————
部分转载于  https://blog.csdn.net/qq_33709508/article/details/101822329





    推荐阅读