2017-07-24 32 views
1

一般來說,我想使用Bash從命令行而不是Python讀取,所以我有選項卡完成功能。我想盡可能以最簡單的方式做到這一點。但是,我無法使下面的代碼正常工作,我想了解是什麼導致了這個問題。沒有這樣的文件或目錄錯誤與Python中的subprocess.call

的Python腳本:

from subprocess import call 
call(['read', '-ep', 'Path:', 'temporaryPath']) 
print temporaryPath 

錯誤回溯:

Traceback (most recent call last): 
    File "tmp.py", line 2, in <module> 
    call(['read', '-ep', 'Path:', 'temporaryPath']) 
    File "/usr/lib64/python2.6/subprocess.py", line 478, in call 
    p = Popen(*popenargs, **kwargs) 
    File "/usr/lib64/python2.6/subprocess.py", line 642, in __init__ 
    errread, errwrite) 
    File "/usr/lib64/python2.6/subprocess.py", line 1238, in _execute_child 
    raise child_exception 
OSError: [Errno 2] No such file or directory 
+1

'read'是bash內建的,不是二進制。 –

回答

3

你試圖調用read這是一個shell內建:

$ type read 
read is a shell builtin 

和內置有這種特殊的外殼沒有同等課程:

$ which read 
$ 

所以Python將無法找到它在你的PATH環境變量,根據strace

[pid 17266] execve("/usr/local/bin/read", ["read", "-ep", "Path:", "temporaryPath"], [/* 70 vars */]) = -1 ENOENT (No such file or directory) 
[pid 17266] execve("/usr/bin/read", ["read", "-ep", "Path:", "temporaryPath"], [/* 70 vars */]) = -1 ENOENT (No such file or directory) 
[pid 17266] execve("/bin/read", ["read", "-ep", "Path:", "temporaryPath"], [/* 70 vars */]) = -1 ENOENT (No such file or directory) 
[pid 17266] execve("/usr/local/games/read", ["read", "-ep", "Path:", "temporaryPath"], [/* 70 vars */]) = -1 ENOENT (No such file or directory) 
[pid 17266] execve("/usr/games/read", ["read", "-ep", "Path:", "temporaryPath"], [/* 70 vars */]) = -1 ENOENT (No such file or directory) 
[…] 
[pid 17266] write(4, "OSError:", 8 <unfinished ...> 

但是,如果你明確要求Python的使用shell來執行你的命令,外殼本身將能夠運行其內置read

$ python3 
Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import subprocess 
>>> subprocess.call('read', shell=True) 
/bin/sh: 1: read: arg count 
2 
>>> subprocess.call('read foo', shell=True) 
hello world 
0 

您現在有一個新的問題:內置read被存儲讀取值作爲一個shell變量的外殼,這將diseapear無線在呼叫subprocess.call之後,外殼正在死亡。

哦,在read shell內建中,你也沒有完成。如果您想交互式地向用戶提問,或者如果不需要交互,只需使用argparse解析用戶作爲命令行參數提供的內容即可,您應該只使用input,這樣用戶在鍵入命令行參數時就會有一些shell完成參數通常不在標誌上,因爲用戶shell不知道它們,但是在路徑上。

+0

感謝您向我展示argparse,它看起來像一個非常強大的方式來完成我想要的。另外,我現在明白了爲什麼call要求'shell = True',但爲什麼以下不工作? 'call('read -ep \「Path:\」temporaryPath; export temporaryPath',shell = True)' – digitaLink

+0

'export'不允許您修改調用進程的環境。什麼都不會允許你修改你的調用過程的環境。但是你仍然可以'echo $ temporaryPath'並從流程stdout中獲取值(不要這樣做,最好使用'input',甚至更好地使用'argparse')。 –

+0

啊,現在看起來很明顯。謝謝! – digitaLink

相關問題