最小限の、DRY、美しい方法で同じディレクトリにある複数のファイルを実行する方法は?

最小限の、DRY、美しい方法で同じディレクトリにある複数のファイルを実行する方法は?

私はUbuntu 16.04を使用しており、私のGitHubプロジェクトを自分のコンピュータにダウンロードした後に得られた多くのファイルを実行するローカライズファイルがあります。

ファイルにはという名前のBashスクリプトが含まれていますlocalize.sh。サブセッションで実行します~/${repo}/localize.sh

このファイルには、子セッションですべての関連ファイルを実行するための同じ基本パターン(以下を参照)を持つ複数行が含まれています。

ファイルの実際の内容は次のとおりです。

#!/bin/bash
~/${repo}/apt/security.sh
~/${repo}/apt/lemp.sh
~/${repo}/apt/certbot.sh
~/${repo}/apt/misc.sh

~/${repo}/third-party/pma.sh
~/${repo}/third-party/wp-cli.sh

~/${repo}/conf/nginx.sh
~/${repo}/conf/php.sh
~/${repo}/conf/crontab.sh

~/${repo}/local/tdm.sh

繰り返しパターンを見ることができます~/${repo}/

これは大きな問題ではありませんが、ファイルが大きくなる必要があるため、重複する文字を減らすことをお勧めします。

DRYを実装する最も簡単な方法は何ですか(繰り返さないでくださいこのコードのバージョンは何ですか?

私は個人的にこの場合、長いワイヤを使用したくありません。

編集:原則として、.txtにリストされているファイル以外のファイルはリストされたディレクトリには存在せず、存在しないでくださいlocalize.sh


localize.shさらに、名前やファイルを呼び出す動作はlocalization悪いアプローチかもしれません。間違って書かれたと思われる場合は、私を批判し、注意事項を指摘してください。

答え1

実行中かどうかわからないみんなスクリプトは関連ディレクトリにありますが、そうであればrun-parts便利です。

for subdir in apt third-party conf local
do
    run-parts --regex '\.sh$' ~/${repo}/${subdir}
done

これにより、各ディレクトリ内で英数字順にスクリプトが実行されるため、サブディレクトリ内の順序が重要な場合は、名前を変更するか番号を付ける必要があります。run-parts次のオプションを使用して実行すると、実行する作業を事前に確認できます--test

apt/certbot.sh
apt/lemp.sh
apt/misc.sh
apt/security.sh
third-party/pma.sh
third-party/wp-cli.sh
conf/crontab.sh
conf/nginx.sh
conf/php.sh
local/tdm.sh

答え2

シンプルで短い「find ${repo} -exec {}\;」はどうですか?

私のサンプルスクリプトは、「foo」、「bar」、または「baz」をエコーし​​ます。

$ repo=~/scripts/bash/foo; find ${repo} -type f -iname "*.sh" -exec {} \;
foo
baz
bar

「エイリアス」を使用して短縮することもできます。

$ alias run_myscripts='repo=~/scripts/bash/foo; find ${repo} -type f -iname "*.sh" -exec {} \;'

または $alias run_myscripts='find ~/scripts/bash/foo -type f -iname "*.sh" -exec {}\;'

その後実行

run_myscripts

ファイルに実行フラグが必要であることを確認しました。そうでない場合や不明な場合は、次のように "find ... -exec"コマンドを拡張できます。

find ${repo} -type f -iname "*.sh" -exec bash {} \;'

編集:良いです。順序が維持されなければならないことを知りませんでした。これはわずかな変化をもたらします。良い方法は、注文をテキストファイルに入れ、実行行の周りに「読み取り行」をラップすることです。

while read line; do 
    bash ~/${repo}/$line
done < ordered_scripts.txt 

order_scripts.txtで正しい順序を定義できます。

apt/security.sh
apt/lemp.sh
apt/certbot.sh
apt/misc.sh
third-party/pma.sh
third-party/wp-cli.sh
conf/nginx.sh
conf/php.sh
conf/crontab.sh
local/tdm.sh

答え3

すべてのスクリプトが共通の親ディレクトリにあると仮定すると、~/${repo}それを配列に入れて繰り返すことができます。

SCRIPTS=(apt/security.sh apt/lemp.sh apt/certbot.sh apt/misc.sh
         tp/pma.sh tp/wp-cli.sh conf/nginx.sh conf/php.sh conf/crontab.sh
         local/tdm.sh)

for SCRIPT in ${SCRIPTS[@]}; do
    ~/${repo}/${SCRIPT}
done

答え4

GNU並列処理を使用する:

parallel ::: ~/${repo}/*/*.sh

直列化が必要な場合:

parallel -j1 ::: ~/${repo}/*/*.sh

これにより、スクリプトが英数字順に実行されるため、順序が重要な場合は、ディレクトリとフォルダの名前を次のように変更して実行される内容を確認01_apt/01_security.shできます。--dry-run

一致するファイルが多すぎる場合(別のディレクトリなど)、そのディレクトリに直接言及してください。

parallel ::: ~/${repo}/{apt,third-party,conf,local}/*.sh

順序が重要な場合:

parallel -j1 ::: \
  ~/${repo}/{apt/{security,lemp,certbot,misc},third-party/{pma,wp-cli},conf/{nginx,php,crontab},local/tdm}.sh

最後の種類は、長い行を避けたいあなたの希望に反しています。

空白行を許可する垂直バージョン:

parallel -rj1 ~/${repo}/{} <<_EOF
apt/security.sh
apt/lemp.sh
apt/certbot.sh
apt/misc.sh

third-party/pma.sh
third-party/wp-cli.sh

conf/nginx.sh
conf/php.sh
conf/crontab.sh

local/tdm.sh
_EOF

関連情報