at ジョブは #!/bin/bash があるにもかかわらず、/bin/sh を使用して実行されているようです。

at ジョブは #!/bin/bash があるにもかかわらず、/bin/sh を使用して実行されているようです。

を使用してジョブを実行しようとしていますが、スクリプトがありますatbash最初の行があります)。ただし、スクリプト内で使用すると#!/bin/bash操作が失敗するため、生成されたスクリプトには次のものが表示されます。[[]]mail

=sh: 58: [[: not found
=sh: 58: [[: not found
=sh: 58: [[: not found
=sh: 58: [[: not found
=sh: 58: [[: not found

ここに/bin/shリンクがありますdash。しかし、私のスクリプトにshe-bang行がある場合は#!/bin/bashそれを使用してはいけませんかbash

PSプロンプトでスクリプトを実行すると、bashエラーなしでうまく機能します(実行権限もあります)。

- 編集する -

次のようにタスクを追加します。

$ at 1:30 am today -f /path/to/my/script.sh



$ which bash 
/bin/bash

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 30  2012 /bin/sh -> dash

$ uname -a
Linux server1 3.5.0-46-generic #70~precise1-Ubuntu SMP Thu Jan 9 23:55:12 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

答え1

POSIXは定義します存在する利用できるシェルあるいは、環境変数を使用します/bin/shが、これに限定されません。

シェル

at-jobを呼び出すために使用されるコマンドソルバーの名前を決定します。変数が設定されていないか空の場合は、shを使用する必要があります。 sh 名前以外の値に設定されている場合、実装は次のいずれかを実行する必要があります。そのシェルを使用し、ユーザーデータベースでログインシェルを使用するか、選択した警告診断を伴います。

-katの一部の実装では、Kornシェル、-cCシェルなど、実行するシェルを選択できます。そして、すべての実装が代替をat許可するわけではありません。したがって、POSIXはまた、他のシェルを使用する安定した方法が次のようになることを保証します。SHELLsh明示的に呼び出す:

一部の実装では、SHELLは他のシェルの代わりに使用できません。たとえば、System Vシステムはすでに/etc/passwdでユーザーのログインシェル値を使用しています。他のコマンドソルバーを確実に選択するには、ユーザーはスクリプトの一部として含める必要があります。例:

$1800

マイシェルマイスクリプト

酸化エチレン

仕事...から...$

簡単な方法は、stdinに渡されたbash実行スクリプトをbash script次のように使用することですat

echo "bash /path/to/yourscript" | at <time>

例:

echo "bash /path/to/yourscript" | at 16:30

bash /path/to/yourscript今日は16時30分に実行されます。

答え2

atそしてbatch:

標準入力または指定されたファイルから後で実行するコマンドを読み取るには、/bin/sh を使用します。

POSIX 定義at入力ように:

以下に説明するシェルコマンド言語で許可されるコマンドで構成されるテキストファイルシェルコマンド言語

つまり、必須POSIXshスクリプトになります。 Bashはbashで実行されていてもbashismを通過することを許可しshますが、dash非常に厳格です。スクリプトは実行可能ファイルとして実行されず、runを使用して直接実行されるため、sh任意のバイナリやPythonスクリプトを実行することはできません。


しかし、あなたができることは、bash何があっても自分自身を強制することです。それは次のとおりです。

[ "$BASH_VERSION" ] || exec bash "/path/to/script"

ファイルの一番上にbashスクリプトがこのように解釈されていない場合は、スクリプトを独自に再実行する必要があります。シェルは実行時に到達していないコードに対して構文エラーを生成しないため、後で使用しても[[問題になりません。$0パスの代わりに使用することもできますが、at実装間で一貫性がないように見え、パスがより安定しているように動作する必要があるという仕様はありません。

答え3

私の答えはGnoucの答えと似ていますが、「なぜ?」のより良い説明があると思います。あなたがそう言うときat … -f /path/to/my/script.sh、あなたはat読むように言っています/path/to/my/script.sh。タスクデーモンがスクリプトの内容をに渡すこと/var/spool/cronができるように、スクリプトをどこか(おそらく下)にコピーします。この時点で、シャバンラインは単なるコメントであり、使い方が間違っていました。atdat/bin/sh#!/bin/bash[[…]]

やりたいことはatあげないコンテンツあなたの台本を与える名前、通過

$ echo /path/to/my/script.sh | at 1:30 am today

または

今朝1時30分$
/パス/to/my/script.sh
Ctrl+D

これにより、コマンドとして表示および/bin/sh実行されます。/path/to/my/script.shそしてそれからshe-bang 行がその役割を果たしてbash呼び出されます。

atdPS私の答え(Gnoucのような)には、今から今日の午前1時30分の間にスクリプトを変更すると、修正されたバージョンを実行する「機能」があります。 (これを使用して実行時にスクリプトのコピーを作成する-f方法とは対照的です。)特にスクリプトを削除または名前を変更すると、何も実行されません。atat

関連情報