Moj*_*ian 3 linux bash shell-script
我需要编写一个 shell 脚本,.sh如果它们存在于目录模式中,它可以执行所有文件。就像是:
##!/bin/bash
sh /var/scripts/*/my_*.inc.sh
Run Code Online (Sandbox Code Playgroud)
但是上面的脚本只执行了一个文件;发生的第一个文件(似乎是由最新修改日期选择的),这不是我的观点。我需要执行与规则匹配的所有文件。
您的代码不起作用的原因是文件名通配模式扩展时会发生什么。
该模式将扩展为匹配路径名的列表。脚本中的代码将sh使用此列表调用。这意味着它将执行第一个匹配的名称作为脚本,并将其他名称作为该脚本的参数:
sh /var/scripts/dir/my_first.inc.sh /var/scripts/dir/my_second.inc.sh /var/scripts/dir/my_third.inc.sh
Run Code Online (Sandbox Code Playgroud)
相反,只需遍历匹配的名称:
sh /var/scripts/dir/my_first.inc.sh /var/scripts/dir/my_second.inc.sh /var/scripts/dir/my_third.inc.sh
Run Code Online (Sandbox Code Playgroud)
这假设每个匹配的名称都是一个应该由sh(not bash)执行的脚本。如果单个文件是可执行的并且具有正确的#!-line,sh则从上面循环中的脚本调用中删除。如果文件被“点脚本”,应源即脚本,然后更换sh用.,而不是让脚本在当前脚本的环境中执行。
请注意,上面的脚本可以是sh脚本 ( #!/bin/sh),因为它不使用任何bash功能。如果其他脚本是“点脚本”,那么您显然必须将其更改为#!/bin/bash或需要其他任何解释器来获取脚本。
一个.inc.sh扩展建议.inc.sh应该包含这些文件,或者换句话说,它们的内容应该被一个shell 解释器评估为 shell 代码,这样同一个 shell 解释器可以执行一些其他代码,函数,变量,别名...定义在那些可用的文件中。
bash的语法大多与sh语法向后兼容,特别是当它的 POSIX 模式被启用时(当调用为时bash实际上是一个sh解释器sh),所以即使这些函数可能是用sh语言编写的,你仍然应该能够让bash解释器解释它们.
bash(当不在 POSIX 模式下)和之间的一个显着区别sh是bash不能alias在脚本中进行扩展。这可以通过设置expand_aliases选项或posix选项来解决,因此您可以执行以下操作:
#! /bin/bash -
set -o posix # increase POSIX sh compatibility, some but not all bash-specific
# extensions are still available.
for file in /var/scripts/*/my_*.inc.sh; do
. "$file"
done
# rest of the code that uses the functions/variables, etc defined
# in the files sourced above with the "." special builtin
Run Code Online (Sandbox Code Playgroud)
请注意,如果没有匹配的文件,则.在尝试获取不存在的文件/var/scripts/*/my_*.inc.sh并退出 shell时,该命令将失败。
如果在这种情况下你不想做任何你可以做的事情:
shopt -s nullglob
files=(/var/scripts/*/my_*.inc.sh)
shopt -u nullglob
for file in "${files[@]}"; do
command . "$file"
done
Run Code Online (Sandbox Code Playgroud)
使用nullglob,没有匹配项的 glob 扩展到空列表而不是未扩展的模式。使用command前缀,特殊内置函数的失败.(例如 when$file不可读)不会导致 shell 退出(并且仍应报告错误)。
要.inc.sh递归查找文件而不仅仅是 的子目录/var/scripts,您可以使用该globstar选项来启用**运算符:
shopt -s nullglob globstar
files=(/var/scripts/**/my_*.inc.sh)
shopt -u nullglob globstar
Run Code Online (Sandbox Code Playgroud)
在任何情况下,名称以.(隐藏的)开头的目录和文件都将被省略。dotglob如果要包括,请使用该选项,
显然,如果任何源脚本调用exit或exec有语法错误或任何调用的特殊内置函数失败,也将退出脚本。
| 归档时间: |
|
| 查看次数: |
4827 次 |
| 最近记录: |