7

スクリプトの内部から、スクリプトを起動するために使用した正確なコマンドを確認したいと思います。私は次のことを試しました:

#!/usr/bin/env python

import sys, os
print os.path.basename(sys.argv[0]), sys.argv[1:]

しかし、それは情報を失います:

$ 1.py -1 dfd  'gf g' "df df"
1.py ['-1', 'dfd', 'gf g', 'df df']

コマンドで、二重引用符、一重引用符を使用したか、引用符がまったくないかについての情報がすでに失われています。

編集

これが私が使っているものです。私のスクリプトのすべての引数にはデフォルト値があり、引数が次のように解析された後argparse

args = parser.parse_args()

私はそれらをログに記録するか、ログがある場合は-それらを上書きします:

logName = "." + (os.path.splitext(os.path.basename(sys.argv[0])))[0] + ".json"
if os.path.exists(logName):
    print "!!! I've found log", logName
    Args = bk_loads_json(logName)
    for arg in Args:
        exec('args.{0} = Args["{0}"]'.format(arg))
else:
    print "!!! the log of args is saved to", logName
    bk_saves_json(args.__dict__, logName)

言及されたdefuns:

def bk_saves_json(myCustomDct, flNm):
    "Takes dict, and writes it to the file."

    FlNm = open(flNm, 'w')
    tmpJsn = json.dumps(myCustomDct, sort_keys=True, indent=4)
    FlNm.write(tmpJsn)
    FlNm.close()

def bk_loads_json(flNm):
    "Takes file of the json and returns it as a dict."

    json_data=open(flNm)
    data = json.load(json_data)
    json_data.close()
    return data
4

2 に答える 2

11

探している情報(引用符を含むコマンドパラメータ)は利用できません。

Pythonではなくシェル(bash)が引用符を読み取り、解釈します。Pythonまたはその他の生成されたプログラムがパラメーターを認識するまでに、引用符は削除されます。(もちろん、引用符を除いて。)

より詳しく

シェルにコマンドを入力するときは、引用符を使用して、コマンドライン上のどのトークンを単一のパラメーターとして処理するかをシェルに指示します。空白はコマンドラインを個々のパラメーターに分割するために使用され、引用符はそれをオーバーライドするために使用されます。つまり、パラメーターを区切るのではなく、パラメーター内に空白を含めるためです。

次に、シェルは実行可能ファイルをフォークし、パラメーターのリストを実行可能ファイルに渡します。引用符で囲まれていない引用符は、コマンドラインの解析でシェルによってすでに「使い果たされている」ため、この段階では事実上存在しなくなり、コマンド(python)は引用符を認識しません。


ちなみに、なぜあなたは見積もりを取得することを気にするのか疑問に思う必要があります。一見、見当違いのように思われると言わざるを得ません。なぜあなたがそれらを必要と感じているのか教えていただければ、おそらく私たちは助けることができますか?

編集

以下のOPのコメントに応えて、元のコマンドラインを出力する方法を次に示します。少なくとも1つは機能的に同等です。

import pipes # or shlex if python3
print sys.argv[0], ' '.join( [pipes.quote(s) for s in sys.argv[1:]] )

すべてのパラメータを引用符で囲むだけです。

于 2012-09-13T17:29:45.817 に答える
7

私は使用することをお勧めします:

import subprocess, sys
print subprocess.list2cmdline(sys.argv[1:])

list2cmdline、引数のリストをシェルから使用できる単一の文字列に変換するために使用されます。ドキュメントから:

MS Cランタイムと同じルールを使用して、一連の引数をコマンドライン文字列に変換します。

1)引数は、スペースまたはタブのいずれかである空白で区切られます。

2)二重引用符で囲まれた文字列は、空白が含まれているかどうかに関係なく、単一の引数として解釈されます。引用符で囲まれた文字列を引数に埋め込むことができます。

3)円記号が前に付いた二重引用符は、文字通りの二重引用符として解釈されます。

4)円記号は、二重引用符の直前にない限り、文字通りに解釈されます。

5)円記号が二重引用符の直前にある場合、円記号のすべてのペアは文字通りの円記号として解釈されます。バックスラッシュの数が奇数の場合、ルール3で説明されているように、最後のバックスラッシュは次の二重引用符をエスケープします。

于 2012-09-13T18:02:11.687 に答える