# Execute a command:
$ bash -c "command"
# Run commands from a file:
$ bash file.sh
# Run commands from a file, logging all commands executed to the terminal:
$ bash -x file.sh
# Run commands from a file, stopping at the first error:
$ bash -e file.sh
# Run commands from stdin:
$ bash -s
Shell 执行中的错误
当shell脚本执行过程中发现shell脚本存在错误时(比如使用了一个未定义的变量),该错误代码会被跳过,并且继续执行错误代码之后的所有代码(而不是立刻执行当前shell脚本的执行)
Bash 的模式扩展
?
字符扩展
?
字符代表文件路径里面的任意单个字符,不包括空字符。比如,Data???
匹配所有Data
后面跟着三个字符的文件名。
# 存在文件 a.txt 和 b.txt
$ ls ?.txt
a.txt b.txt
上面命令中,?
表示单个字符,所以会同时匹配a.txt
和b.txt
。
如果匹配多个字符,就需要多个?
连用。
# 存在文件 a.txt、b.txt 和 ab.txt
$ ls ??.txt
ab.txt
上面命令中,??
匹配了两个字符。
?
字符扩展属于文件名扩展,只有文件确实存在的前提下,才会发生扩展。如果文件不存在,扩展就不会发生。
# 当前目录有 a.txt 文件
$ echo ?.txt
a.txt
# 当前目录为空目录
$ echo ?.txt
?.txt
上面例子中,如果?.txt
可以扩展成文件名,echo
命令会输出扩展后的结果;如果不能扩展成文件名,echo
就会原样输出?.txt
。
*
字符扩展
*
字符代表文件路径里面的任意数量的字符,包括零个字符。
# 存在文件 a.txt、b.txt 和 ab.txt
$ ls *.txt
a.txt b.txt ab.txt
# 输出所有文件
$ ls *
下面是*
匹配空字符的例子。
# 存在文件 a.txt、b.txt 和 ab.txt
$ ls a*.txt
a.txt ab.txt
$ ls *b*
b.txt ab.txt
注意,*
不会匹配隐藏文件(以.
开头的文件)。
# 显示所有隐藏文件
$ echo .*
# 与方括号扩展结合使用,
# 只显示正常的隐藏文件,不显示 . 和 .. 这两个特殊文件
$ echo .[!.]*
*
字符扩展也属于文件名扩展,只有文件确实存在的前提下才会扩展。如果文件不存在,就会原样输出。
# 当前目录不存在 c 开头的文件
$ echo c*.txt
c*.txt
上面例子中,当前目录里面没有c
开头的文件,导致c*.txt
会原样输出。
*
只匹配当前目录,不会匹配子目录。
# 子目录有一个 a.txt
# 无效的写法
$ ls *.txt
# 有效的写法
$ ls */*.txt
上面的例子,文本文件在子目录,*.txt
不会产生匹配,必须写成*/*.txt
。有几层子目录,就必须写几层星号。
Bash 4.0 引入了一个参数globstar
,当该参数打开时,允许**
匹配零个或多个子目录。因此,**/*.txt
可以匹配顶层的文本文件和任意深度子目录的文本文件。详细介绍请看后面shopt
命令的介绍。
Reference
- man bash
- https://blog.csdn.net/guodongxiaren/article/details/38402577
- https://blog.csdn.net/huangchunxia_1/article/details/79649481
- https://blog.csdn.net/guodongxiaren/article/details/39544805
- https://blog.csdn.net/column/details/wanbash.html
- https://wangdoc.com/bash/grammar.html