cronは非常に希薄なPATHを使用して私のbashスクリプト(バックアップスクリプト)を呼び出します/usr/bin:/usr
。その結果、
lvcreate --size 1G --snapshot ...
端末でスクリプトを実行するとスクリプトは正常に動作しますが、crontabで実行するとlvcreateが見つかりません。同様の問題を説明します。ここしかし、私は根本的な問題に対処するための一般的な戦略にもっと興味があります。
これまでに思いついた考え:
簡単な解決策として、スクリプトの上部にPATHを手動で設定しました。 crontabでもこれを行うことができます。システム全体のPATHが変更された場合は、これらの行をすべて手動で更新する必要があるかもしれません。
より永久的な解決策は、私のスクリプトで絶対パスを使用することです。たとえば、呼び出しを
/sbin/lvcreate --size 1G ...
(RPi)lvcreateが/usr/bin/にあるものに置き換えます。which
各コマンドに対してPATHを正しく設定し、結果を保存し、スクリプトの上部にローカルエイリアスを設定できますが、これは少し混乱しているようです。私は/ etc / environmentを調達することを検討しました。これは私のUbuntuコンピュータで動作しますが(通常のDebianでも同じだと思います)、私のRPiではシステム全体のPATHが設定されていません。私は同じ理由で.bashrcまたは同様のファイルを使用することを躊躇します(さまざまなディストリビューションで特定のファイルの場所や使用に依存したくありません)。
だから私の質問は:スクリプトが設定されたPATHに依存せずに移植性を維持するための良い方法は何ですか?最先端の方法はありますか?
答え1
明示的に設定されますPATH
。
スクリプトでこれを行う場合は、現在の設定に追加でき、$PATH
その中にあるすべての内容を尊重して失わないようにしたいものだけを追加できます。
#!/bin/bash
PATH=$PATH:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin
...
PATH
実際、cron自体の欠点を解決しているので、crontab構成で設定する方が適切です(環境変数を設定できる場所)。スクリプトを変更するよりもcronで変更する方が合理的です。
cronで設定した場合、PATH
現在の値を参照できないため、設定を完了する必要があります。
# my user's crontab
PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
0 2 * * * /usr/local/bin/my2amjob.sh
(一部のシステムによって、または後述のディレクトリにインストールされている単純なバージョンの「オーバーレイ」をインストールするかどうかによって、ディレクトリの順序が若干異なる場合がありますが、システム$PATH
の現在の設定を確認して可能であることを確認してください。)
これがあなたの問題を解決することを願っています。
システム全体のPATHが変更された場合は、これらの行をすべて手動で更新する必要があるかもしれません。
正直なところ、私はそれについてあまり心配しません。ディストリビューションには常に、/usr/bin
または下にバイナリがインストールされているため、パスを変更せ/usr/sbin
ずに常にアクセスできます。 Distrosは長い間新しいディレクトリを含めるように更新することを悪夢と考えていたので、これを避け、代わりにホームディレクトリにシンボリックリンクまたはラッパースクリプトを追加しました。/bin
/sbin
$PATH
bin
アップデートに推奨される直接インストールされたソフトウェアの場合は、以下$PATH
にシンボリックリンクまたはラッパースクリプトを生成し、可能であれば/usr/local/bin
変更を避けることをお勧めします。$PATH
Linuxディストリビューションもこれらの違いを解決するためにいくつかの措置を講じています$PATH
。
まず/usr
努力の統合、それは/bin
シンボリックリンクに/usr/bin
なり/sbin
、シンボリックリンクになります/usr/sbin
。すべてのバイナリは/usr
(パッケージがより簡単に)インストールされますが、スクリプトはまだいくつかの絶対パスを介してそれを参照する/bin/mytool
か、/sbin/mytool
シンボリックリンクを介して動作し続けます。これはFedora、ArchLinuxなどのディストリビューションですでに採用されており、Debian、Ubuntuなどの他のディストリビューションでも現在の採用段階を経ています。
ArchLinuxはさらに一歩進んだようです。sbin
一緒にマージbin
。したがって、統合機能を備えた最新のArchLinuxでは、可能な4つの絶対パスのいずれかでバイナリを参照して見つけることができます。他のディストリビューションでも2番目のマージを採用するかどうかはまだわかりません。
最後に、cronのより現代的な代替案を検討することもできます。 Cronはあなたが経験している露出環境のような多くの機能を持っていますが(ロギングシステムを使用するのではなく)、コマンド出力に電子メールを使用し、厄介なコマンドラインエスケープも使用します。
パッケージをインストールせずに組み込みシステムタイマーをサポートするUbuntuとArchLinuxに言及しました。
使い方に関する素晴らしい記事があるArchLinux Wikiをチェックしてください。特に、次の点を確認したい場合があります。cronの交換でsystemdタイマーを使用するには、特定のユースケースに役立つ特定のレシピがあります。