Sto eseguendo Python 3.4.3 su Linux 3.16.0. Voglio usare subprocess.Popen
per eseguire un comando con un singolo argomento lungo (una complessa invocazione di Bash), circa 200 KiB.Perché il sottoprocesso.Popen ha un limite di lunghezza dell'argomento inferiore a quello segnalato dal sistema operativo?
Secondo getconf
e xargs
, questo dovrebbe essere ben entro i miei limiti:
$ getconf ARG_MAX
2097152
$ xargs --show-limits < /dev/null
Your environment variables take up 3364 bytes
POSIX upper limit on argument length (this system): 2091740
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2088376
Size of command buffer we are actually using: 131072
Tuttavia, Python viene a mancare con limiti molto più piccoli:
>>> subprocess.Popen('echo %s > /dev/null' % ('a' * (131072-4096)), shell=True, executable='/bin/bash')
<subprocess.Popen object at 0x7f4613b58410>
>>> subprocess.Popen('echo %s > /dev/null' % ('a' * (262144-4096)), shell=True, executable='/bin/bash')
Traceback (most recent call last):
[...]
OSError: [Errno 7] Argument list too long
Nota che il limite di Python è più o meno lo stesso come il "reale utilizzo" del buffer di comando xargs
segnalazioni. Questo suggerisce che xargs
è abbastanza intelligente per iniziare con un limite più piccolo e aumentarlo secondo necessità, ma Python non lo è.
Domande:
- Perché limite inferiore al limite del sistema operativo 2MiB Python?
- Posso aumentare il limite Python?
- Se sì, come?
Non utilizzare l'API "single string" di 'subprocess.Popen()'. Passa sempre una lista invece. Evita 'shell = True'. –
In questo caso, in realtà sto facendo affidamento sulle funzionalità di Bash nel sottoprocesso. – Reid
Provare il sottoprocesso.Popen ('echo $ SHELL') '. Penso che ti darà '/ bin/sh', non bash. –