sql >> データベース >  >> RDS >> Mysql

subprocess.Popenが子プロセスが終了するまで待機しないのはなぜですか?

    subprocess.Popen 、インスタンス化されると、プログラムを実行します。ただし、それを待つことはありません。cmd &と入力したかのように、バックグラウンドで起動します。 シェルで。したがって、上記のコードでは、基本的に競合状態を定義しています。挿入が時間内に終了できる場合は正常に見えますが、そうでない場合は予期しない出力が得られます。最初のrun()を待っていません PIDを終了するには、Popenを返すだけです。 インスタンスと継続。

    この動作がドキュメントとどのように矛盾するかはわかりません。Popenには、次のように、待機されていないことを示す非常に明確なメソッドがいくつかあるためです。

    Popen.wait()
      Wait for child process to terminate. Set and return returncode attribute.
    

    ただし、このモジュールのドキュメントが改善される可能性があることに同意します。

    プログラムが終了するのを待つには、subprocessを使用することをお勧めします の便利なメソッド、subprocess.call 、またはcommunicateを使用する Popenで オブジェクト(stdoutが必要な場合)。 2回目の通話ではすでにこれを行っています。

    ### START MAIN
    # copy some rows from a source table to a destination table
    # note that the destination table is empty when this script is run
    cmd = 'mysql -u ve --skip-column-names --batch --execute="insert into destination (select * from source limit 100000)" test'
    subprocess.call(cmd)
    
    # check to see how many rows exist in the destination table
    cmd = 'mysql -u ve --skip-column-names --batch --execute="select count(*) from destination" test'
    process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    try: count = (int(process.communicate()[0][:-1]))
    except: count = 0
    

    さらに、ほとんどの場合、シェルでコマンドを実行する必要はありません。これはそのようなケースの1つですが、コマンドをシーケンスのように書き直す必要があります。そうすることで、従来のシェルインジェクションを回避し、次のように引用符を気にする必要がなくなります。

    prog = ["mysql", "-u", "ve", "--execute", 'insert into foo values ("snargle", 2)']
    subprocess.call(prog)
    

    これも機能し、期待どおりに注入されません:

    prog = ["printf", "%s", "<", "/etc/passwd"]
    subprocess.call(prog)
    

    インタラクティブに試してみてください。特にユーザー入力を受け入れる場合は、シェルインジェクションの可能性を回避します。シーケンスを機能させるのに問題が発生したため、サブプロセスと通信するためのあまり優れていない文字列メソッドを使用していると思われます:^)



    1. 2つのフィールドの個別の組み合わせを、個別の組み合わせが発生したカウントとともにクエリする必要があります

    2. Pythonのプロセス間でpostgresdbへの接続を共有する

    3. IDの自動インクリメントをリセットしますか? phpmyadmin

    4. 一意のIDを指定して、前の行から列が変更された行のみを選択します