1行のbashループで&(アンパサンド)を使用する

1行のbashループで&(アンパサンド)を使用する

設定ファイルの変数を変更し、ループでPythonスクリプトを実行するこのコマンドを正常に使用しました。

for((i=114;i<=255;i+=1)); do echo $i > numbers.txt; python DoMyScript.py; done

DoMyScript.pyインスタンスは終了する前に実行するのに約30秒かかりますので、次のインスタンスを作成することができますが、そのインスタンスをバックグラウンドに下げたいと思います。

私は次のようなアンパサンドを追加して、私が慣れていることを試しました。

for((i=114;i<=255;i+=1)); do echo $i > numbers.txt; python DoMyScript.py &; done

ただし、これにより次のエラーが発生します。

-bash: syntax error near unexpected token `;'

答え1

;背面を取り外します&。これは構文要件

for((i=114;i<=255;i+=1)); do echo $i > numbers.txt;python DoMyScript.py & done

答え2

スティーブンの意見を考えると1_CRの答え、次のことができます。

for i in {114..255}; do { echo $i > numbers.txt && python DoMyScript.py; } & done

答え3

失う;

for((i=114;i<=255;i+=1)); do echo $i > numbers.txt;python DoMyScript.py & done

答え4

他の答えは次のとおりです。

  • 問題は;後であります&
  • ;後者を削除すると、&コマンドはシェル構文エラーなしで実行されます。ただし、競合状態が発生するため、正常に動作しない可能性があります。

OPは、3秒の遅延を追加して競争条件を解決したと述べた。

誰も言及していません:

  • 今日は3秒遅れが可能です。明日は、コンピュータがさらに遅くなり、再び誤動作する可能性があります。来年はスクリプトを修正して時間がかかり、再び失敗する可能性があります。遅延時間を30秒ずつ増やすと、失敗の確率が低下します。もちろん、これはスクリプトプロセスが本質的に同時(並列)ではなく逐次実行されるため、プロセスを非同期化する目的が失われることを意味します。
  • スクリプトの複数のインスタンスを実行する必要がある場合は、コマンドラインで数値引数を受け入れるようにスクリプトを変更することをお勧めします。
    for ((i=114;i<=255;i++)); do python DoMyScript.py --number="$i" & done
    
    そしてファイルを削除してください。
  • スクリプトを変更できない場合は、次の回避策が機能します。
    for i in {114..125}; do ( subdir="dir.$i" && mkdir "$subdir" && cd "$subdir" && 
              echo "$i" > numbers.txt && python ../DoMyScript.py; cd .. && rm -r "$subdir" ) & done
    
    これはnumbers.txt別々の実行ディレクトリを提供し、スクリプトプロセスごとに別々のファイルを提供します。ディレクトリを作成および削除し、サブシェルでスクリプトを実行します。
    • DoMyScript.py相対パス名以外のファイルにアクセスする場合は、それに対応するように上記のコマンドを調整する必要がnumbers.txt あります。

    • 上記のインスピレーションは以下から来ています。グレンジャックマンの答え (私は私がうまくいき、その人はうまくいかないと思いますが)。

    • コマンドBコマンドが成功したかどうかによって異なりますAもしそうなら、防御プログラミングは良いです。ただし、これはこの状況を処理する理想的な方法ではないかもしれません。失敗すると、次の111回の試行も失敗し、112個のエラーメッセージが表示されます。致命的なエラーが発生した場合は、ループを中断するのが最善です。A && BABmkdir dir.114

      タスクが非同期サブシェルで発生するという事実により、これは少し難しいです。

      for i in {114..125}; do
              { subdir="dir.$i" && mkdir "$subdir" && echo "$i" > "$subdir"/numbers.txt; } || break;
              ( cd "$subdir" && python ../DoMyScript.py; cd .. && rm -r "$subdir" ) & done
      

      mkdir 1 つ以上のコマンドが失敗すると、ループは中断されます。echo value > file

    • たとえば、書き込みが「保証」されたディレクトリで作業する方が良いかもしれません  /tmp。ただし、これにより、コマンドが他のプロセスと衝突(干渉)する危険性が高まります。

      • たとえば、  $$ディレクトリ名を追加してこの問題を軽減できます。dir.$$.$idir.$BASHPID
      • mkdir これにより、ファイルシステムがいっぱいになり、ファイルの作成に失敗するリスクは排除されません。
    • スクリプトが失敗しても、上記のコードは引き続き実行され、一時ディレクトリを削除します。この場合、他の操作を実行できます。

      • こんな。何らかの理由でmkdir "$subdir"成功しましたがcd "$subdir"失敗した場合は、引き続き実行されますcd .. && rm -r "$subdir"。親ディレクトリと同じ名前のディレクトリ  dir.114(つまり、現在のディレクトリと平行)がある場合、そのディレクトリは削除されます。最後の行を次のように変更すると、この問題を(少なくともある程度)解決できると思います。
        ( cd "$subdir" && { python ../DoMyScript.py; cd ..; } && rm -r "$subdir" ) & done
        
        または絶対パスを使用してくださいsubdir="$PWD/dir.$i"

関連情報