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 viabg, 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.
-
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.shRun it:
$ ./test.sh I'm a shell & here are my flags: hBSee it? The only flags are
h(“hashall”) &B(“braceexpand”)—noifor “interactive”. ↩ -
“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! ↩
-
For example:
$ history <snip> 500 ssh moe 501 ssh larry 502 ssh curly $ !501 ssh larryUse
historyto 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. ↩ -
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 BonjourNow let’s turn on the
noclobberoption & see what happens:$ set -C $ echo $- himBCH $ cat test Bonjour $ echo "Hello" > test -bash: test: cannot overwrite existing fileStopped in our tracks. Note that we could still delete the file,
cpanother file overtest, 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 & turnnoclobberoff:$ set +C $ echo $- himBH $ cat test Bonjour $ echo "Hello" > test $ cat test Hello
本文详细介绍了UNIX Shell Flags的概念、作用及如何通过命令查看和修改这些设置,包括交互性、历史命令重用、文件重定向等常用功能。通过实践示例,展示了如何创建并运行非交互式Shell脚本,以及Shell Flags对命令执行的影响。
801

被折叠的 条评论
为什么被折叠?



