web-dev-qa-db-ja.com

実行中にシェルスクリプトを編集する

実行中にシェルスクリプトを編集し、実行中のスクリプトに変更を反映できますか?

バッチがさまざまなビルドフレーバーを実行し、一晩中実行するcshスクリプトの特定のケースに興味があります。操作中に何かが発生した場合は、コマンドを追加して追加するか、実行されていないコマンドをコメントアウトします。

可能でない場合、これを可能にするシェルまたはバッチ機構はありますか?

もちろん試してみましたが、それが機能するかどうかを確認するまでには数時間かかります。

75
ack

[編集]回避策については この回答、セクション も参照してください。

それはdoes影響します、少なくとも私の環境ではbashですが、非常に不快な方法で。これらのコードをご覧ください。最初 a.sh

#!/bin/sh

echo "First echo"
read y

echo "$y"

echo "That's all."

b.sh

#!/bin/sh

echo "First echo"
read y

echo "Inserted"

echo "$y"

# echo "That's all."

行う

$ cp a.sh run.sh
$ ./run.sh
$ # open another terminal
$ cp b.sh run.sh  # while 'read' is in effect
$ # Then type "hello."

私の場合、出力は常に次のとおりです。

こんにちは
こんにちは
それだけです。
それだけです。

これは予測できないため、危険です。回避策については、 この回答、セクション を参照してください。

[追加]正確な動作は、1つの余分な改行に依存します。また、Unixフレーバー、ファイルシステムなどにも依存する可能性があります。 「読み取り」行。

44
teika kazura

これを試してください... "bash-is-odd.sh"というファイルを作成します。

#!/bin/bash
echo "echo yes i do odd things" >> bash-is-odd.sh

これは、bashが実際にスクリプトを「そのまま」解釈していることを示しています。実際、実行時間の長いスクリプトを編集すると、ランダムな文字を挿入するなどの結果が予測できません。なぜですかbashは最後のバイト位置から読み取るため、編集すると読み取られる現在の文字の位置がシフトします。

一言で言えば、Bashはこの「機能」のために非常に安全ではありません。 svnとrsyncをbashスクリプトで使用する場合、デフォルトでは結果を「マージ」するので、特に厄介です。 rsyncには、これを修正するモードがあります。 svnとgitはサポートしていません。

私は解決策を提示します。 「/ bin/bashx」というファイルを作成します。

#!/bin/bash
source "$1"

スクリプトで#!/ bin/bashxを使用し、bashではなく「bashx」で常に実行します。これにより問題が修正されます-スクリプトを安全にrsyncできます。

@ AF7によって提案/テストされた代替(インライン)ソリューション:

{
   # your script
} 
exit $?

中括弧は編集を防ぎ、出口は追加を防ぎます。もちろん、bashに '-w'(ファイル全体)などのオプションが付属している場合、またはこれを行う何かがあれば、私たちの方がはるかに良いでしょう。

34
Erik Aronesty

スクリプトを関数に分割し、関数が呼び出されるたびに、source別のファイルから関数を呼び出します。その後、いつでもファイルを編集でき、実行中のスクリプトは次にソースが取得されたときに変更を取得します。

foo() {
  source foo.sh
}
foo
17
glenn jackman

良い質問!このシンプルなスクリプトがお役に立てば幸いです

#!/bin/sh
echo "Waiting..."
echo "echo \"Success! Edits to a .sh while it executes do affect the executing script! I added this line to myself during execution\"  " >> ${0}
sleep 5
echo "When I was run, this was the last line"

Linuxでは、実行中の.shに加えられた変更が、実行中のスクリプトによって実行されるように思えます。

2
Will Turner

これがすべて単一のスクリプト内にある場合は、機能しません。ただし、サブスクリプトを呼び出すドライバースクリプトとして設定した場合、呼び出される前、またはループしている場合は再度呼び出される前にサブスクリプトを変更できる可能性があります。実行に反映されます。

1
Ethan Shepherd

Cshをインストールしていませんが、

#!/bin/sh
echo Waiting...
sleep 60
echo Change didn't happen

それを実行し、最後の行をすばやく編集して読む

echo Change happened

出力は

Waiting...
/home/dave/tmp/change.sh: 4: Syntax error: Unterminated quoted string

うん.

シェルスクリプトの編集は、再実行されるまで有効になりません。

1
dave4420

興味深い副次的な注意-Pythonスクリプトを実行している場合、それは変わりません。 (これは、シェルがどのようにPythonスクリプトを実行するかを理解している人なら誰でも明白に明らかですが、この機能を探している人にとっては便利なリマインダーかもしれないと考えました。)

私が作成しました:

#!/usr/bin/env python3
import time
print('Starts')
time.sleep(10)
print('Finishes unchanged')

次に、別のシェルで、これがスリープしている間に最後の行を編集します。これが完了すると、おそらく.pyc?を実行しているため、変更されていない行が表示されます。 UbuntuとmacOSでも同じことが起こります。

1
Chris

私は聞いていません...しかし、いくつかの間接的なものはどうですか:

BatchRunner.sh

Command1.sh
Command2.sh

Command1.sh

runSomething

Command2.sh

runSomethingElse

次に、BatchRunnerが正しく実行される前に、各コマンドファイルの内容を編集できる必要がありますか?

[〜#〜] or [〜#〜]

よりクリーンなバージョンでは、BatchRunnerは単一のファイルを参照し、一度に1行ずつ連続して実行します。次に、最初のファイルが正常に実行されている間に、この2番目のファイルを編集できるはずです。

0
ack