crontab で引用符付きの環境変数を使用するにはどうすればよいでしょうか?

crontab で引用符付きの環境変数を使用するにはどうすればよいでしょうか?

私の問題の最小限の例は、次のような crontab をインストールしようとしていることです。

FOO="foo\"bar\"bin"

0 0 1 * * ls

実行することによってcrontab crontab(ファイル名にそれがありますcrontab)。次のエラーで失敗します。

% crontab crontab
"crontab":0: bad minute
crontab: errors in crontab file, can't install

\"問題の原因は、エスケープされた引用符 です。

crontab の環境変数で引用符をエスケープするにはどうすればよいですか。

もう少し詳しく説明すると、私は手動で書かれたcrontabに変数を書いているだけではありません。このcrontabは次のように生成されます。いつでも(Ruby gem) には約 70 個のエントリがあり、すべての環境変数を取得して crontab に変数として格納するため、すべての資格情報がスクリプトで利用できるようになります。問題は、最近引用符を含む複雑なものを追加したため、このシステムが壊れてしまったことです。

ご興味があれば、変数を生成する Ruby コードは次のとおりです。

ENV.each do |key, value|
  env key.to_sym, value.inspect
end

答え1

良い実践方法は次のとおりcronです。

  1. コマンドを実行するスクリプトを作成する
  2. スクリプトで変数を設定します。変数を含む外部ファイルを使用することもできます。source /path/to/file/with/variables
  3. コマンドへのフルパスを使用する/usr/bin/ls
  4. ユーザーのホームやパスなどに依存しないでください

rubyここでは、異なる環境でプログラムを実行する 1 つのシェル スクリプトを作成する方法の例を示します。

次のcronようなレコードがあります (例):

0 1 * * * /path/script 1
0 2 * * * /path/script 2

スクリプト自体は次のようになります。

#!/bin/bash
a=$1
case "$a" in

1)  source /path/file1
    /path/to/ruby <parameters>
    ;;
2)  source /path/file2
    /path/to/ruby <parameters>
    ;;
<snip>

*) # do something if parameter is not enumerated
   ;;
esac

そしてfile1次のような内容を含む(例)

RUBYVAR1_1=1
RUBYVAR1_2=2

そしてfile2

RUBYVAR2_1=12
RUBYVAR2_2=22

答え2

man 5 crontab

crontab のアクティブな行は、環境設定または cron コマンドのいずれかになります。環境設定は次の形式です。

 name = value

ここで、等号 (=) の前後のスペースはオプションであり、値内の後続の先頭以外のスペースは、name に割り当てられる値の一部になります。値の文字列は、先頭または末尾の空白を保持するために引用符 (単一または二重、ただし一致) で囲むことができます。

したがって、二重引用符を含む文字列を一重引用符で囲むとうまくいくはずです。

crontab でテスト済み:

var = 'this"contains"quotes'

* * * * * /usr/bin/env  >> /tmp/env

これにより、二重引用符が var 内に適切に保存されるようです。

cat /tmp/env

HOME=/home/HBruijn
LANG=C.UTF-8
SHELL=/bin/sh
var=this"contains"quotes

しかし、私は前の回答と意見にも同意します。cron は適切なスクリプト環境ではなく、多くの制限がある単なる古いジョブ スケジューラであり、複雑さに似たものはすべてオフロードして、ジョブ自体に含める必要があります。

答え3

私が調べた限りでは、crontab 変数には引用符を付けることができず、また 999 文字を超える長さにすることもできません。この質問に対する答えは、それは単に不可能だということです。

関連情報