Bashスクリプトから各ディレクトリを読み取り、操作を実行します。

Bashスクリプトから各ディレクトリを読み取り、操作を実行します。

私は次のディレクトリ構造を持っています/var/sync

# tree -d /var/sync/
/var/sync/
├── sync_bi
│   ├── replicator => Replicator.php
│   sync.php 
├── sync_pfizer
│   ├── replicator => Replicator.php
│   sync.php
│ replicator.sh
│ sync.sh

ご覧のとおり、sync_*各ディレクトリには名前の付いたスクリプトがありsync.phpreplicator各ディレクトリには名前の付いたスクリプトがありますReplicator.php。毎晩このスクリプトを実行する必要があります。Replicator.php午前00:00に実行し、sync.php午前12:30に実行する必要があります。ここで正しいパスは明らかにクローン操作であることがわかります。 2つのスクリプトを作成し、ほぼ同じコードを共有しreplicator.shますsync.shが、最大の違いはスクリプト名です。以下のコードをご覧ください。

replicator.sh
#! /bin/bash
cd $1
/usr/bin/php Replicator.php

sync.sh
#! /bin/bash
cd $1
/usr/bin/php sync.php

次に、次のようにそれぞれのcronjobを追加します。

0 0 * * * /var/sync/replicator.sh /var/sync/sync_bi/replicator/
0 30 * * * /var/sync/sync.sh /var/sync/sync_bi/
0 2 * * * /var/sync/replicator.sh /var/sync/sync_pfizer/replicator/
30 2 * * * /var/sync/sync.sh /var/sync/sync_pfizer/

これらすべての説明の基本的なアイデアは、スクリプトを1回のcronjob呼び出しですべてのタスクを実行し、維持するファイルの数を減らすことができるスクリプトに変更して環境を最適化することです。だから私はいくつかの調査を行い、いくつかの有用なトピックを見つけました。

  • 私が使用しfind some/dir -type f -execdir somecommand {} \;たのと同じことを達成する正しい方法ですか?cd
  • そして、ルートパスの下の各ディレクトリに移動します。私の場合/var/sync

     for D in ./*; do
        if [ -d "$D" ]; then
            cd "$D"
            run_something
            cd ..
        fi
    done
    

私が言う擬似コードは次のとおりです(十分に明確ではない場合に備えて)。

read tree structure at /var/sync
foreach (directory in root+path)
    if (directory_name is replicator)
        cd replicator/
        /usr/bin/php replicator.php
    else if (directory_name is sync_*)
        cd sync_*/
        /usr/bin/php sync.php
endforeach

私はbashの専門家ではないので、私の意思コードを私が望むことを達成することができる機能的なものに翻訳するのを手伝ってください。どんな提案や助けがありますか?

修正する

私が間違っているかもしれませんが、あなたがやろうとしていることにまったく従わないのです。したがって、イベントの順序は次のようになります。

# Run Replicator at mid day and mid night
# this two can run at same time since they are pushing data to different DBs
/var/sync/sync_bi/replicator/Replicator.php
/var/sync/sync_pfizer/replicator/Replicator.php

# Run sync at mid day and mid night
# this two should run one first and the second after 30 min since they are 
# pushing data to the same DBs and second depends on first one
/var/sync/sync_bi/sync.php
/var/sync/sync_pfizer/sync.php

この情報を考えると(まずはわからないので申し訳ありません)、ソリューションはどのように機能しますか?今はすでに持っているので、それともこの問題を解決するために何かを変更する必要がありますか?

ベストアンサー1

これにより、擬似コードがbashに変換されます。

#!/bin/bash
cd /var/sync
for dir in sync*/ ; do
    ( # Subshell to make "cd" not global.
        cd "$dir"
        [[ -f sync.php ]] && /usr/bin/php sync.php
        if [[ -d replicator ]] ; then
            cd replicator
            [[ -f replicator.php ]] && /usr/bin/php replicator.php
        fi

    )
done

しかし、sync.phpとReplicator.phpの両方を実行しましたが、もともと異なる時間に呼び出すことを望んでいました。たぶん良い

#!/bin/bash

run=$1

cd /var/sync
for dir in sync*/ ; do
    ( # Subshell to make "cd" not global.
        cd "$dir"
        [[ -f "$run" ]] && /usr/bin/php "${run##*/}"
    )
done

次のようにcronから呼び出されます。

0 30 * * * /path/to/script.sh sync.php
0 0 * * * /path/to/script.sh replicator/Replicator.php

${run##*/}最後のものより前のすべてを削除します/。つまり、デフォルト名のみが返されます。

修正する

次のようにスクリプトを実行したい場合:

0:00 sync_a/sync.php
0:30 sync_a/replicator/Replicator.php
1:00 sync_b/sync.php
1:30 sync_b/replicator/Replicator.php
2:00 sync_c/sync.php
...

しばらく、ディレクトリ構造を変更するたびにcrontabを再生成できます。

#!/bin/bash
add=$1
php=/usr/bin/php
hour=0
minute=0

update_time () {
    (( minute += add ))
    if (( minute >= 60 )) ; then
        (( hour += minute / 60 ))
        (( minute %= 60 ))
    fi
    if (( hour > 11 )) ; then
        echo "Can't fit into a day!"
        exit 1
    fi
}
cd /var/sync

for dir in sync*/ ; do
    if [[ -f "$dir"/sync.php ]] ; then
        echo $minute $hour 0 0 0 "$php" /path/to/run.sh "$dir" sync.php
        update_time

        if [[ -f "$dir"/replicator/Replicator.php ]] ; then
            echo $minute $hour 0 0 0 "$php" path/to/run.sh "$dir" Replicator.php
        fi
        update_time
    fi
done

呼ぶgenerate_crontab.sh 30か似ています。ファイルはアルファベット順にソートされるため、一部のディレクトリは変更後にスキップされる可能性があります。

run.shただしなければならない

dir=$1
script=$2
if [[ -f "$dir$script" ]] ; then
    cd "$dir"
    /usr/bin/php $script
fi

おすすめ記事