.sh
ディレクトリパターン内のすべてのファイルを実行できるシェルスクリプトを作成する必要があります。それは次のとおりです。
##!/bin/bash
sh /var/scripts/*/my_*.inc.sh
ただし、上記のスクリプトは1つのファイルのみを実行します。最初に発生したファイル(最後の変更日によって選択されたように見えます)は私のポイントではありません。ルールに一致するすべてのファイルを実行する必要があります。
答え1
コードが機能しないのは、ファイル名のワイルドカードパターンが拡張されたときに発生するためです。
このモデルは次に拡張されます。リスト一致するパス名。スクリプトのコードはsh
このリストを使用して呼び出します。これは、最初に一致する名前をスクリプトとして実行し、他の名前を次のように指定することを意味します。議論このスクリプトでは:
sh /var/scripts/dir/my_first.inc.sh /var/scripts/dir/my_second.inc.sh /var/scripts/dir/my_third.inc.sh
代わりに、一致する名前を繰り返すだけです。
#!/bin/sh
for name in /var/scripts/*/my_*.inc.sh; do
sh "$name"
done
sh
これは、一致する各名前が実行される必要がある(ない)スクリプトであると仮定しますbash
。そのファイルが実行可能で正しい行を持っている場合は、上記のループのスクリプト呼び出しからそのファイルを削除してください#!
。sh
ファイルが「ドットスクリプト」、つまりソースを提供する必要があるスクリプトである場合は、スクリプトが現在のスクリプトのコンテキストで実行されるようにするには、次のようにsh
置き換えます。.
上記のスクリプトはどの機能も使用しないため、sh
script()にすることができます。他のスクリプトが「ドットスクリプト」の場合、スクリプトを取得するには明らかに変更する必要があるか、別のインタプリタが必要な場合があります。#!/bin/sh
bash
#!/bin/bash
答え2
拡張子は、.inc.sh
これらの.inc.sh
ファイルが次のようになることを示します。含むつまり、その内容はシェルコードで評価する必要があります。一つ同じシェルインタプリタを使用できるようにするシェルインタプリタ機能、変わりやすい、ニックネーム...利用可能なファイルで定義されています。
bash
彼らのsh
文法bash
。sh
sh
sh
bash
bash
(POSIXモードでない場合)との間の重要な違いの1つは、スクリプトが拡張をサポートしていないこと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
一致するファイルがない場合は、文字通り.
存在しないファイルをインポートしてシェルを終了しようとすると、/var/scripts/*/my_*.inc.sh
コマンドは失敗します。
この場合、何もしたくない場合は、次のことができます。
shopt -s nullglob
files=(/var/scripts/*/my_*.inc.sh)
shopt -u nullglob
for file in "${files[@]}"; do
command . "$file"
done
を使用すると、nullglob
一致しない glob が非拡張パターンではなく空のリストに展開されます。接頭辞を使用すると、command
特殊な組み込み関数が失敗したため.
(たとえば、$file
読み取れない場合など)、シェルは終了しません(エラーを報告し続ける必要があります)。
.inc.sh
サブディレクトリの代わりにファイルを繰り返し検索するには、/var/scripts
このオプションを使用して演算子をglobstar
有効にできます。**
shopt -s nullglob globstar
files=(/var/scripts/**/my_*.inc.sh)
shopt -u nullglob globstar
.
いずれにせよ、名前が(hidden)で始まるディレクトリとファイルは省略されます。dotglob
以下を含めるには、このオプションを使用します。
明らかに、ソーススクリプトが失敗内で呼び出された場合、構文エラーがある場合、または特殊な組み込み関数が呼び出された場合、スクリプトもexit
終了exec
します。
答え3
シェルスクリプト(bashを含む)でファイルを繰り返す最も安全な方法は、forループでパス名拡張(ワイルドカード)を使用することです。正しいコードは次のとおりです。
for file in /var/scripts/*/my_*.inc.sh
do
echo "Executing $file"
"$file"
done
スペース、アスタリスク、改行などの特殊文字を含むパスとファイル名を処理します。
再帰検索が必要な場合、またはglobbingで使用できないオプションを使用したい場合は、-exec
このオプションと一緒にfindを使用できます(次は最近のGNU検索を想定しています)。
find a/ -executable -type f -name '*.sh' -exec {} \;
findがまだ必要ですが、各ファイルで複数のコマンドを実行したい場合はそれをread
使用できますが、すべてのファイル名のオプションに注意する必要があります(次はbashとGNU findを想定しています)。
#!/bin/bash
find a/ -executable -type f -name '*.sh' -print0 |
while IFS= read -r -d $'\0' file
do
echo "Executing $file"
"$file"
done
答え4
次のように for
ループを(再帰的に)使用して、見つかったパス内のすべてのシェルファイルを繰り返すことができます。find
for i in $(find /var/scripts/ -type f -name '*.sh')
do sh "$i"
done