PATHなしでbashスクリプトでコマンドを実行する移植可能な方法

PATHなしでbashスクリプトでコマンドを実行する移植可能な方法

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$PATHbin

アップデートに推奨される直接インストールされたソフトウェアの場合は、以下$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タイマーを使用するには、特定のユースケースに役立つ特定のレシピがあります。

関連情報