When I run emconfigure ./configure I get the following error:
ERROR:root:Exception thrown when invoking Popen in configure with
args: "./configure"!
Traceback (most recent call last):
File "/usr/local/bin/emconfigure", line 13, in <module>
emconfigure.run()
File "/usr/local/Cellar/emscripten/1.37.21/libexec/emconfigure.py", line 46, in run
shared.Building.configure(sys.argv[1:])
File "/usr/local/Cellar/emscripten/1.37.21/libexec/tools/shared.py", line 1533, in configure
process = Popen(args, stdout=None if EM_BUILD_VERBOSE_LEVEL >= 2 else stdout, stderr=None if EM_BUILD_VERBOSE_LEVEL >= 1 else stderr, env=env)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1335, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Break-down:
This one can be tricky to track down because of the depth of the call stack. Let's break it apart:
At the "next-to-top level": a file you're trying to execute cannot be found.
One level lower than that things become clear: subprocess.Popen is trying to execute args.
What's in args? - basically ./configure (as passed by emscripten). export the EM_BUILD_VERBOSE=3 environmental variable and then stderr should display this.
So, the next-to-top level ./configure is directing things in an invalid fashion. Now it's time for a guess at the top level (not knowing what's in the ./configure script): is some line of the shell command in the ./configure script file itself trying to execute something non-existent? E.g.: some point after #! /bin/sh ? - try debugging just ./compile.
It is worth noting that a subprocess can have issues with relative paths (not getting PATH), and permissions (./configure is locked-down), but your error very well may persist even after /you/make/an/absolute/call/to/configure and 777 the permissions of configure. - In that case the previous paragraph is the likeliest culprit.
Editorializing:
The reason this error is interesting as a general one for emscripten is that part (much) of emscripten's raison d'etre is to port [legacy] C/++ code to new JS apps. Well, old C/++ builds get old in the sense of this question. If that's true, this is will be a generally-occurring problem, and, if it is general the community could use a general pattern for resolution.
If you're using Docker, your host computer is Windows, and you mounted it to a Windows directory, make sure that your files aren't \r\n line endings but instead \n line endings. Changing this fixed it for me.
In this case, if you're using git, you might try setting git config core.autocrlf input to stop checking out to \r\n. If you need to convert a file, try this answer out.
Related
I'm using check_output to do all my SSH and GitHub setup, and I'm attempting to execute eval $(ssh-agent), both to start the agent and to parse the output if I need the process id.
from subprocess import check_output
out = check_output(["eval", "$(ssh-agent)"])
print(out)
But regardless of how I escape things, I get the same error.
Traceback (most recent call last):
File "gitSetup.py", line 3, in <module>
out = check_output(["eval", "$(ssh-agent)"])
File "/usr/lib/python2.7/subprocess.py", line 216, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 394, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1047, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
I'm wondering if I'm not escaping or trimming my arguments properly; if anyone sees my error, I'd appreciate some insight!
Even if you managed to fix the superficial syntax problems, a subprocess which runs successfully simply then terminates without a trace; it doesn't attempt to (and couldn't, even if it wanted to) modify the environment of the parent Python process. This is a common FAQ.
You could run the eval in the parent process which starts your Python script, or perhaps figure out how to communicate with ssh-agent directly from Python. Its output is usually a simple sequence of variable assignments, which you can parse yourself.
from subprocess import check_output
from os import environ
eval_string = check_output(['ssh-agent'])
for line in eval_string.rstrip('\n').split('\n'):
for expr in line.rstrip(';').split(';'):
if expr.startswith((' export ', 'echo ')):
continue
var, value = expr.strip().split('=', 1)
environ[var] = value
If the output from ssh-agent contains shell quoting, you will need to perform additional parsing on it (basically, trim the quotes around the value string). But this is already rather clunky and brittle, so perhaps revert to setting up the environment before launching Python instead of trying to splash some sophistication onto this kludge.
In more detail, ssh-agent and a precious few other shell utilities have a very specific design in order for them to be able to communicate with their parent process. Precisely because a subprocess cannot make any changes in the environment of its parent process, it instead prints a piece of code for its parent process to execute. By default, it prints sh code like this:
SSH_AUTH_SOCK=/tmp/ssh-MUyniqn10506/agent.10506; export SSH_AUTH_SOCK;
SSH_AGENT_PID=10507; export SSH_AGENT_PID;
echo Agent pid 10507;
There is also an option for it to print similar code in csh syntax (this is a historical shell which thankfully isn't used much any longer) but, alas, no option for producing Python code. (It would not be hard to make ssh-agent do that, per se.)
(The above output sample copy/pasted from http://blog.joncairns.com/2013/12/understanding-ssh-agent-and-ssh-add/ which contains a fuller explanation.)
I wanted to use this library to scrape data from otodom. I've read the docs however I'm stuck on a very basic level, trying to do basic import. The code I use is taken directly from the docs. On top of that I've tried to launch example.py from Github but I'm getting the same error.
Here's the excerpt from the code:
import otodom, os, logging
from otodom.category import get_category
from otodom.offer import get_offer_information
Error message I get:
Traceback (most recent call last):
File ".\otodom_import.py", line 2, in
from otodom.category import get_category
File "C:\Users\Dom\Anaconda3\lib\site-packages\otodom\category.py", line 9, in
from otodom.utils import get_response_for_url, get_url
File "C:\Users\Dom\Anaconda3\lib\site-packages\otodom\utils.py", line 14, in
from scrapper_helpers.utils import caching, normalize_text, key_sha1,
get_random_user_agent
File "C:\Users\Dom\Anaconda3\lib\site-packages\scrapper_helpers\utils.py",
line 22, in
MAX_FILENAME_LENGTH = subprocess.check_output("getconf NAME_MAX /",
shell=True).strip()
File "C:\Users\Dom\Anaconda3\lib\subprocess.py", line 336, in check_output
**kwargs).stdout
File "C:\Users\Dom\Anaconda3\lib\subprocess.py", line 418, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'getconf NAME_MAX /' returned non-zero
exit status 1.
Thanks in advance!
EDIT: Don't understand downvotes, I realize that this is a niche module but I did my homework. I've read the docs and tried to find help in other places. If there is a chance that as a noobie I'll find at least one person that can help me, why wouldn't I use this opportunity? Even info that module is buggy can help.
getconf, which the dependency scrapper_helpers module is trying to call, is a POSIX command not available on Windows.
You can track it down in C:\Users\Dom\Anaconda3\lib\site-packages\scrapper_helpers\utils.py and replace the line 22 with:
MAX_FILENAME_LENGTH = 255
But then the question is what other error might pop up given that the module obviously expects to run on a POSIX-compatible system - for example, it will attempt to use /var/tmp/scrapper-helpers/ as its temporary cache path which is also not available on Windows (but Python will interpret it as <DRIVE_LETTER>:\var\tmp\scrapper-helpers and attempt to create it).
Alternatively, looking at its code, you might get away with just declaring the following environment variables:
set MAX_FILENAME_LENGTH=255
set CACHE_DIR=%TEMP%\scapper-helpers\
This question already has answers here:
python subprocess.call() "no such file or directory"
(2 answers)
Closed 4 years ago.
I'm attempting to run an old script which takes an .mdb file and converts it into a MySQL database. However, I'm running into an issue where I receive the following error.
File "/usr/lib64/python2.7/subprocess.py", line 568, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
I have attempted to research this error, but all I found was fixes where the item was not correctly formatted as a list. So, I've modified the affected code where subprocess.py is called, and changed it to the following:
def get_external_command_output(command):
args = shlex.split(command)
print "################"
print type(args), args
ret = subprocess.check_output(args) # this needs Python 2.7 or higher
return ret
Which in turn returns the same error, but also the below message is printed:
<type 'list'> ['mdb-tables', '-1', '/mnt/data/General/Genit/WIP/IL_Orders.mdb']
So I can safely say that the arguments are correctly formatted as a list. I'm really unsure how else to tackle this issue, because all the help forums I've found suggest the same issue. The argument isn't a list. However, I can see that mine is.
Could anybody provide some guidance here?
Many thanks.
There can be number of reasons for this. The error comes from your underlying OS (ENOENT).
The easiest to would be to try running the same thing:
mdb-tables -1 /mnt/data/General/Genit/WIP/IL_Orders.mdb
(or just mdb-tables really) and see what happens, what complain you get from your shell.
Among possible reasons would be:
As mentioned by Peter Wood in the comments. If you just pass an executable name to run, it must be located in one of the directories listed in your PATH environmental variable. Or, you have to use either path to the executable which is either absolute or relative to current working directory (based on where you ran the parent from or cwd argument passed to subprocess.check_output call). E.g. ./mdb-tables if in the same directory where you were when you ran the parent script or to which cwd was set.
It is also possible. Esp. if it's an older script. That you have specified an interpreter that no longer exists on your host. In that case the same error (ENOENT) would be raised. You might see a slightly different error message (hinting at bad interpreter) if executed directly from shell, but it would look identical when called as subprocess from python.
You've hinted mdb-tables is also a script. But otherwise previous paragraph would also hold true for dynamically linked ELF binaries. If they were built with and expected a version (path) of dynamic linker (their interpreter) no longer available on the system. You can print path of the expected dynamic linker binary for instance by running objdump -sj .interp BINARY_IN_QUESTION.
I am trying to move a series of python scripts from a hpc cluster to the amazon cloud. I have an executable that needs to be called from within the script. I always used os.system to do this, but it would not work when running in the cloud and i think it may have been deprecated. At any rate, it doesn't seem to be the preferred way to handle this, so I switched to subprocess.call. The command line I give works if I type it at the shell prompt:
$needle -outfile=../test.txt_results/Output/Needlescores/OG5_126737_Am_ac_Acasneedle.txt -asequence=../test.txt_results/Temp/Am_ac_Acasseq1.fasta -bsequence=../test.txt_results/Temp/Am_ac_Acasseq2.fasta -gapopen=10 -gapextend=0.5
and it works if I open a python interpreter and use the subprocess.call:
>>> call('needle -outfile=../test.txt_results/Output/Needlescores/OG5_126737_Am_ac_Acasneedle.txt -asequence=../test.txt_results/Temp/Am_ac_Acasseq1.fasta -bsequence=../test.txt_results/Temp/Am_ac_Acasseq2.fasta -gapopen=10 -gapextend=0.5',shell = True)
But, if I run it from within my script I get an error:
OSError: [Errno 12] Cannot allocate memory
I went into the script and changed the call to call('ls', shell = True) and it still gave me the same error so I don't think it has anything to do with my executable using too much memory.
File "/home/ubuntu/Scripts/Taxon/__init__.py", line 541, in runneedle
child = subprocess.call('ls', shell = True)
File "/usr/lib/python2.7/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1143, in _execute_child
self.pid = os.fork()
OSError: [Errno 12] Cannot allocate memory
I looked around for people who have had similar errors, and there was one very technical (to my inexperienced eyes) answer about forks - but it didn't seem specific enough to help me and I don't know how I would handle something like this, especially in an EC2 instance.
Has anyone had this problem - and found a solution - or does anyone have advice for someone fairly new to working in linux and in the cloud?
I am trying to generate a set of files through a python script on a 48-core cluster which actually has a master-and 3 slave machines. I need to generate a set of files, run some scripts on them, collect results and then delete them. I again repeat the process- regenerate files, execute, delete etc.,
When I delete and regenerate files with the same name, I see that the slave machine complains that it cannot find the files.
I am running python script through os.system()
I learnt from this post that it is better to use subprocess.Popen() rather than os.system so that it actually waits for my script to generate my files, before proceeding with the execution. I could use os.system("pause") or time.sleep(whatever) for waiting, but I want to convert my os.systems to subprocess.popens or subprocess.calls and I am stuck here.
I ran through the python documentation and tried out subprocess.Popen('ls'), but I am not able to get a simple thing like subprocess.Popen('cd /whatever_directory') working.
It might sound silly but how do I execute such a simple command like cd through subprocess rather than os.system('cd')?
Then, I actually want to convert the following into subprocess. How do I do it?
import os,optparse
from optparse import OptionParser
parser.add_option("-m", "--mod",dest='module', help='Enter the entity name')
parser.add_option("-f", "--folder", dest="path",help="Enter the path")
module=options.module
path=options.path
os.system('python %s/python_repeat_deckgen_remote.py -m %s' %(path,module))
I just replaced os.system with subprocess.Popen.
But it gave me a lot of complaints:
File "/usr/lib64/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib64/python2.6/subprocess.py", line 1139, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
As NPE already noted, new processes don't affect the existing one (which means os.system('cd /some/where') also has no effect on the current process). In this case, though, I think you're tripping over the fact that os.system invokes a shell to interpret the command you pass in, while subprocess.Popen does not do so by default. But you can tell it to do so:
proc = subprocess.Popen(
'python %s/python_repeat_deckgen_remote.py -m %s' % (path, module),
shell = True)
status = proc.wait()
If you're invoking a shell built-in command or using shell expansions, it's necessary to invoke the shell (assuming you're not willing to simulate it):
>>> import subprocess
>>> x = subprocess.Popen('echo $$')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/local/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
>>> x = subprocess.Popen('echo $$', shell = True); x.wait()
81628
0
>>>
but you can bypass the shell—which can help with security issues—if your problem permits, by breaking up the command arguments into a list:
>>> x = subprocess.Popen(['echo', '$$']); x.wait()
$$
0
>>>
Note that this time the output here is the string $$, rather than a process ID, since this time the shell did not interpret the string.
For your original example, for instance, you might use:
proc = subprocess.Popen(['python',
os.path.join(path, 'python_repeat_deckgen_remote.py'),
'-m',
module])
which avoids issues if path and/or module contain characters special to the shell.
(You might even want to call subprocess.Popen with cwd = path and eliminate the call to os.path.join, although that depends on other things.)
I am not able to get a simple thing like subprocess.Popen('cd /whatever_directory') working.
Each process's current working directory is independent of other processes in the system.
When you start a subprocess (using either of these mechanisms), and get it to cd into another directory, that has no effect on the parent process, i.e. on your Python script.
To change the current working directory of your script, you should use os.chdir().
I might be not answering you question directly, but for such tasks which require running subprocess, I always use plumbum.
IMO, It makes the task much simpler and more intuitive, including running on remote machines.
Using plumbum, in order to set subprocess's working directory, you can run the command in a with local.cwd(path): my_cmd() context.