2017-07-07 57 views
1

我有一個python腳本,我想提供一個包含通配符的參數(通常是),引用一系列我想要的文件喜歡做東西。例如這裏:防止在UNIX環境中運行時引用非引號python腳本參數中的通配符

#!/usr/bin/env python 

import argparse 
import glob 

parser = argparse.ArgumentParser() 
parser.add_argument('-i', action="store", dest="i") 
results = parser.parse_args() 
print 'argument i is: ', results.i 
list_of_matched_files = glob.glob(results.i) 

在這種情況下,如果用戶增加了引號,像這樣傳遞的參數一切都很正常:

./test_script.py -i "foo*.txt" 

...但很多時候用戶忘記報價添加到參數並在列表僅包含第一個匹配項時被阻止,因爲UNIX已經擴展了列表並且只有argparse才獲得第一個列表元素。

有沒有一種方法(在腳本內)阻止UNIX在將它傳遞給python之前擴展列表?或者,甚至只是爲了測試參數是否不包含引號,然後警告用戶?

+0

查看'sys..argv'來查看'argparse'從shell中獲取的內容。 – hpaulj

回答

1

它不是在做擴展的UNIX,而是shell。

Bash有一個選項set -o noglob(或-f),它關閉通配符(文件名擴展),但這是非標準的。

如果您允許最終用戶訪問命令行,那麼他們真的應該知道引用。例如,常用的find命令有一個-name參數,它可以採用glob結構,但必須以類似的方式引用它們。你的程序與其他程序沒有區別。

如果用戶無法處理,那麼也許你應該給他們一個不同的界面。你可以去編寫一個圖形用戶界面或網頁/ HTML前端的極端,但這可能是頂級的。

或者爲什麼不提示輸入文件名模式?你可以,例如,使用-p選項,以指示提示,如:

import argparse 
import glob 

parser = argparse.ArgumentParser() 
parser.add_argument('-i', action="store", dest="i") 
parser.add_argument('-p', action="store_true", default=False) 

results = parser.parse_args() 

if results.p: 
    pattern = raw_input("Enter filename pattern: ") 
else: 
    pattern = results.i 

list_of_matched_files = glob.glob(pattern) 
print list_of_matched_files 

(我假設,因爲你print聲明的Python 2)

這裏,輸入不是由外殼,但通過閱讀python,它不會擴展glob構造,除非你問它。

3

編號通配符在腳本運行之前由shell(Bash,zsh,csh,fish,whatever)擴展,而腳本對它們無能爲力。測試參數是否包含引號也不起作用,因爲在將參數傳遞給腳本之前,shell類似地剝去了"foo*.txt"中的引號,因此所有Python都看到的是foo*.txt

1

可以從命令行使用set -f禁用擴展。 (通過set +f重新啓用)。

由於jwodder正確地說,這是在腳本運行之前發生的,所以我唯一能想到的方法是用一個shell腳本封裝它,臨時禁用擴展,運行python腳本,使擴展。在將它傳遞給python之前阻止UNIX擴展列表是不可能的。

相關問題