10

私はほとんどPythonスクリプトを使用していないので、愚かな質問を許してください。

他の人が使用できるように python スクリプトを作成しようとしています。その中で、常にパスを知っているとは限らないプログラムを呼び出す必要があります。それを回避するために、ユーザーにプログラムへのパスを提供するように依頼しますが、これは機能しますが、ユーザーがスクリプトを実行するたびにパスを提供する必要がないため、bash をセットアップしようとしています。 ~/.profile および ~/.bashrc ファイルにスクリプトを追加することにより、エイリアスを作成します。

その後、エイリアスを使用してインタラクティブな bash シェルからプログラムを実行できますが、スクリプトが実行しようとすると、「コマンドが見つかりません」というエラーが発生します...

.bashrc ファイルを再ソースして、「shopt -s expand_aliases」コマンドを使用しようとしましたが、うまくいきませんでした。

私の ~/.bashrc は次のようになります:

alias nuke='/Applications/Nuke6.2v4/Nuke6.2v4.app/Contents/MacOS/Nuke6.2v4'

スクリプトの一部は次のようになります。

os.system('source .bashrc')
os.system('shopt -s expand_aliases')
os.system('nuke -x scriptPath')

しかし、スクリプトがこの時点まで到達すると、次のように返されます。

sh: nuke: command not found

何か間違ったことをしていますか、それともプログラムへのパスを永続的に保存する別の方法はありますか?

4

5 に答える 5

16

必要なモジュールはsubprocessです。

問題の簡単な修正は、次のように subprocess モジュールを使用することです。

import subprocess
sp = subprocess.Popen(["/bin/bash", "-i", "-c", "nuke -x scriptpath"])
sp.communicate()

これは、次の呼び出しと同等です。

nuke -x scriptpath

bash シェルから。-i フラグは、インタラクティブなセッションであるかのように動作するように bash に指示します (そして ~/.bashrc ファイルを使用します)。

ただし、シェル インジェクションにさらされないように注意する必要があります (たとえば、このコマンドが CGI ページから呼び出された場合)。

ユーザーがシェルから直接呼び出す簡単なスクリプトの場合、通常のシェル アクセスよりも多くのダメージを与えることはおそらくできませんが、このスクリプトが Web ページによって呼び出された場合、悪意のあるユーザーは "rm -dfr" のようなものを渡すことができます。 ~/ &" プログラムとして.*

実行可能ファイルの数が少ない場合は、スクリプトでそれらに名前を付ける方がよい場合があります。

PROGRAMS = {"nuke": "/path/to/nuke"
                "foo" : "/path/to/foo" }

# Parse command line args
program = sys.argv[1] 

sp = subprocess.Popen([PROGRAMS[program], "other", "arguments", "to", "program"])

*これはこのように正確に機能しない場合がありますが、アイデアは得られます

于 2011-07-28T10:10:49.043 に答える
4

os.systemはおそらくshではなくを使用しているbashためsourceshoptも失敗することに注意してください。

を使用している場合、呼び出しごとに新しいプロセスが作成されるため、bash失敗します。os.system次のように 1 行で実行できます。

os.system('source .bashrc; shopt -s expand_aliases; nuke -x scriptPath')

ただし、他の方法でパスを取得し (または、必要に応じて手動で読み取ることもでき.bashrcます)、 を使用することをお勧めしますsubprocess.Popen()

于 2011-07-28T09:51:03.463 に答える
3

これは古い質問であることは知っていますが、将来これに遭遇する他の人にとっては、誰かの ~/.bashrc または ~/.profile ファイルを (特に静かに) 変更することは、一般的に失敗するアイデアの 1 つであることを言及する価値があると思います「バッドプラクティス」の傘下。さらに、解決する必要がある問題には少し手荒に思えます。

代わりに、ユーザーのホーム ディレクトリに保存されている独自の構成ファイルをスクリプトで追跡しないのはなぜでしょうか? ConfigParser、ファイルにダンプされた独自の JSON 構造、または必要に応じて他の何かを使用してこれを行うのは非常に簡単です。

次に、スクリプトで最初にそれが存在するかどうかを確認し、存在する場合は、実行可能パスを保持する探しているキーが含まれているかどうかを確認します。これらのテストのいずれかが失敗した場合、ユーザーにパスの入力を求める必要があることがわかります。その時点で、次回のために構成ファイルに書き込むことができます。

于 2014-08-29T19:07:58.133 に答える
0

ええ、そうしないでください。構成を独自のドットファイルに書き出し、を使用せずos.system、を使用しますsubprocess

于 2011-07-28T09:15:17.290 に答える
0

エイリアスは非常に複雑で、シェル環境を使用するための直感的な方法ではないと思います。代わりに環境変数を使用するのはどうですか? それが基本的に彼らの目的です...

ユーザーにエイリアスを定義するよう求める代わりにnuke、環境変数を定義するように求めます$NUKE.bashrcこれにより、または他の構成ファイルをいじる必要がなくなります。ユーザーが追加export NUKE=<path>すると.bashrc、Python スクリプトを対話的に実行するときに環境で自動的に使用可能になります。

システムコールを行うためにこのパスのみが必要な場合は、単に使用してos.system('$NUKE -x scriptPath')ください。

Python で値が必要な場合は、簡単にアクセスできます: afterimport osは、os.environ現在定義されているすべての環境変数の辞書を提供します。逆に、エイリアスが設定されている値を取得することは、python では非常に面倒です。

于 2011-08-06T17:31:46.853 に答える