2016-03-31 241 views
2

私はcrontabのエントリのコメントを解除するsedコマンドを書いています。これを行うより良い方法はありますか?頭に浮かぶ最初の選択肢は、sedです。sedを使用してcrontabを編集する

例:

crontab -l 

# 5 * * * 3 bash test.sh 

のsedコマンドでは、このエントリのコメントを解除する必要があります。これは今私が持っているものです。

sed "s#\# 5 * * * 3 bash test.sh#5 * * * 3 bash test.sh#" 

明らかに、このsedコマンドはタスクを実行しません。

ps:sedコマンドが最終的にスクリプトに変換されます。

+1

代用区切り記号として '# 'を使用している特別な理由はありますか?不要な合併症のようだ。 – ghoti

答えて

2

Sedは、特定の正規表現とのマッチングや特定の方法でのテキスト操作には適していますが、これは私のものではないようです。この作業にsedを使用することはできますが、その結果はおそらく過度に複雑で壊れやすいでしょう。

あなたの最初の試みでした:

sed "s#\# 5 * * * 3 bash test.sh#5 * * * 3 bash test.sh#" 

*文字は正規表現の中の特殊文字であり、この場合は(、A「前のアトムの0以上」と訳されているので、これが失敗しましたスペース)。厳密に言えば、正規表現のアスタリスクをエスケープすることで、このsedスクリプトを動作させることができます(置換パターンでは不要です)。

しかし、これはこの特定のパターンに役立ちます。あなたの同僚の1人が、別のスクリプトとの競合を避けるために、5時でなく6時にこのスクリプトを実行することにしたらどうなりますか?または、コメント文字の後ろにスペースがありますか?突然あなたのsed置換が失敗します。

問題のスクリプトのすべてのコメントの発生をコメントを解除するには、あなたが使用する可能性があります:

crontab -l | sed '/# *\([^ ][^ ]* *\)\{5\}[^ ]*test\.sh/s/^# *//' | crontab - 

あなたがmore modern sedを使用している場合は、わずかに短いEREと、このBREを置き換えることができます:

crontab -l | sed -E '/# *([^ ]+ *){5}[^ ]*test\.sh/s/^# *//' | crontab - 

出力はcrontab -lです。これは明らかに完全なcrontabであり、sedで操作した後、出力に基づいて新しいcrontabをで書き込みます。sedスクリプトは、有効なcrontabのようなものに一致する行を検索します(実際のコメントには単にスクリプトを記述するのを避けるため)。そして、最初にコメント文字のみを削除する単純な置換を行います。スペース

  • [^ ]*続く5非空白文字列、 - - 非任意の数 - ゼロ以上のスペース
  • ([^ ]+ +){5}続いコメント文字にマッチします

    • # *:マッチしたパターンは次のように勃発します空白文字は、最大:
    • test\.sh - あなたのスクリプトにつながります。

    注意は、しかし、これは@reboot@weekly@midnight、などのようなタグを含む可能性のあるすべての有効なcrontabの時間を、一致していないことを詳細man 5 crontabをチェックしてください。


    awkのような非SEDの代替は順序であるかもしれません。次のawkソリューションは私に多くの意味があります:

    crontab -l | awk -v script="test.sh" ' 
        { field=6 } 
        /^#/{ field++ } 
        index($field,script) { sub(/^#/,"") } 
        1' \ 
    | crontab - 
    

    それはほんの少し長いですが、私はそれが簡単に読んで理解することを見つけます。

  • +0

    競合状態の危険性はありませんか? "crontab -l | sed ... | crontab - "を実行すると、シェルはこれらの2つの "crontab"プロセスを同時に実行します。 "crontab -l"が読み込みのために開く前に、 "crontab - "がユーザのcrontabを切り捨てる可能性はありませんか? – tetsujin

    +0

    興味深い質問です。だから...パイプコマンドは同時に実行されます。しかし、 'crontab -'コマンドは、既存のタブを*閉じる*だけ上書きします。そして、この答えの構成では、それを閉じる原因は、前のパイプ要素からの入力の終了です。単に 'crontab -'を起動するだけで既存のタブが消去される危険がありますが、そうではありません。また、crontab -lコマンドを破棄してcrontabをダンプする可能性があるが、それが他の重大な問題を示している場合には、問題が発生する可能性があります。参照:https://unix.stackexchange.com/q/37508/13377 – ghoti

    1

    sedや他のツールを使用しても大きな違いはありません。 私はsedも使います。

    しかし、cronが使用しているものを正しく変更するには、crontabコマンドを使用してください。
    データファイルを編集しないでください(一部のシステムでは/etc/crontabなど)。 Cronは変更を受け取りません!!!

    あなたはパイプを使用することがあります:

    crontab -l | sed -e "s#\# 5 \* \* \* 3 bash test.sh#5 * * * 3 bash test.sh#"| crontab 
    

    変更を実行します。

    実行中のスクリプトに有効/無効の機能を追加するだけでは簡単ではありませんか?

    +0

    有効/無効機能をスクリプトにどのように移動するのですか?あなたは精緻化できますか? – u530891

    +0

    解決策が機能しないrhelを使用しています。7.2 – u530891

    +0

    スクリプトの先頭にチェックを入れてください。例えば。 certein _well-known_ファイルが存在しない場合には中断します(スクリプトの実行が実行される可能性が低い場合は優先します)。逆の場合は、そのファイルが存在する場合は中止します。 – rpy

    関連する問題