Find out what your UNIX shell’s flags are & then change them

Today we enter the semi-arcane world of your UNIX shell’s flags, the variables that determine how your shell will function for you. I’m focusing on the bash shell, as that’s the one I know best.

You can see your current flags by echoing the $- variable, as so:

$ echo $-
himBH

So what do those flags mean? You can type in man bash & search for SHELL BUILTIN COMMANDS & then, once you’ve found that section, scroll down (or search) for the setcommand. There you’ll find all the flags, written in that “kinda-informative-but-kinda-not”man page style we all know & love. Or you can check out “Table 8-13 bash features” onhttp://www.informit.com/articles/article.aspx?p=441605&seqNum=8, which does a nicer job explaining things.

Here’s what my flags mean (note that all of these are defaults):

  • h: Short for “hashall” (read that “hash all”), this tells bash to remember the locations of commands it has found through querying your PATH.
  • i: Short for “interactive”, which is good, because this is a shell with which I’m interacting (entering input & getting back output)!1
  • m: Short for “monitor”, this enables job control in bash (so you can send jobs to the background via bg, for instance).
  • B: Short for “braceexpand” (read as “brace expand”), this allows you to use the very efficient brace expansion in bash2.
  • H: Short for “histexpand” (read as “hist [history] expand”), this is what enables you to re-run a command from your history by prefacing its number with an exclamation point3.

There are several others (by “several” I mean “about 15 or so”), like:

  • e: Short for “errexit”, this causes bash to exit as soon as a command fails. Yikes!
  • C: Short for “noclobber”, this stops you from overwriting files via redirection.4

You can change these flags when you start the shell or after it’s started by using the setcommand. Let’s start with everything working like normal:

$ echo $-
himBH
$ history
<snip>  
500 ssh moe  
501 ssh larry  
502 ssh curly
$ !501
ssh larry

Because the H flag is set, I can re-run a command from history by using the exclamation point. Now I remove that flag (this is a bit confusing, but + removes the flag, while - turns it on) & notice what happens:

$ set +H
$ echo $-
himB
$ history
<snip>  
500 ssh moe  
501 ssh larry  
502 ssh curly
$ !501
-bash: !505: command not found

I can still view my history, but I can’t re-run any commands easily since I disabledhistexpand. Bummer. Let’s turn that back on:

$ set -H
$ echo $-
himBH
$ history
<snip>  
500 ssh moe  
501 ssh larry  
502 ssh curly
$ !501
ssh larry

Now I can use the exclamation point again, & all is swell.

One final thing. Instead of echoing $-, you can quickly see your shell’s current options with a quick set command:

$ set -o
allexport       off
braceexpand     on
emacs           on
errexit         off
errtrace        off
functrace       off
hashall         on
histexpand      on
history         on
ignoreeof       off
interactive-comments    on
keyword         off
monitor         on
noclobber       off
noexec          off
noglob          off
nolog           off
notify          off
nounset         off
onecmd          off
physical        off
pipefail        off
posix           off
privileged      off
verbose         off
vi              off
xtrace          off

The only problem is that the flags aren’t listed here, so you have to do your own cross-indexing using the man page for bash, but it’s still a nice quick way to see what’s on & what’s off. You can also turn flags off & on using these options. So, for instance, to turn off history expansion (“histexpand” above), you’d use set +o histexpand, & to turn it on you’d useset -o histexpand. Same thing as set +H & set -H, respectively. As with many things UNIX, it’s your choice which syntax to use. You can go with brevity or comprehension—it’s up to you.


  1. OK, so how do you “see” a non-interactive shell? Sounds a bit like the observer effect, I know, but we can in fact easily create & view a non-interactive shell in action. Here’s how: create a text file named test.sh & enter into it the following:

    #!/bin/bash
    echo "I'm a shell & here are my flags:"
    echo $-
    

    Save the file, then make it executable:

    $ chmod 755 test.sh
    

    Run it:

    $ ./test.sh
    I'm a shell & here are my flags:
    hB
    

    See it? The only flags are h (“hashall”) & B (“braceexpand”)—no i for “interactive”. 

  2. “Braces” as in “curly braces” as in { & }. An example:

    $ ls
    $ mkdir {test1,test2}
    $ ls
    test1/ test2/
    $ mkdir test{3,4}
    $ ls
    test1/ test2/ test3/ test4/
    

    Pretty cool, eh? A great time-saver! 

  3. For example:

    $ history  
    <snip> 
    500 ssh moe  
    501 ssh larry  
    502 ssh curly  
    $ !501  
    ssh larry
    

    Use history to view the commands you’ve previously entered onto your shell, with each prior command numbered, then re-run a previous command by prefacing its number with an exclamation point. 

  4. By “redirection”, I’m referring to the > or >> command. So, for example:

    $ echo $-
    himBH
    $ echo "Hello" > test
    $ cat test
    Hello
    $ echo "Bonjour" > test
    $ cat test
    Bonjour
    

    Now let’s turn on the noclobber option & see what happens:

    $ set -C
    $ echo $-
    himBCH
    $ cat test
    Bonjour
    $ echo "Hello" > test
    -bash: test: cannot overwrite existing file
    

    Stopped in our tracks. Note that we could still delete the file, cp another file over test, or edit it manually. We just can’t redirect output to that file, a nice safeguard if you’re feeling really paranoid. Now let’s go back to normal & turn noclobber off:

    $ set +C
    $ echo $-
    himBH
    $ cat test
    Bonjour
    $ echo "Hello" > test
    $ cat test
    Hello
    
        
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值