我正在使用自定义脚本运行Flask应用程序。还是尝试,无论如何。
我在Windows 10上,应用程序应在Linux Docker容器中使用以下命令运行:
docker-compose up api
Docker-compose是version 1.23.2。在dockerfile中,该api服务通过以下命令运行:
version 1.23.2
api
command: python manage.py run --host "0.0.0.0" --with-threads
在尝试启动时,我看到了异常
OSError: [Errno 8] Exec format error: '/api/manage.py'
我最初以为这将是“可怕的Windows行尾”,再次给我,但是dos2unix在我的所有源文件上运行都无法解决问题。
dos2unix
如何避免此错误?
manage.py
import click from flask.cli import FlaskGroup from my_app_api import create_app def create_my_app(info): return create_app() @click.group(cls=FlaskGroup, create_app=create_my_app) def cli(): pass if __name__ == "__main__": cli()
全面追溯
api_1 | Traceback (most recent call last): api_1 | File "manage.py", line 22, in <module> api_1 | cli() api_1 | File "/usr/local/lib/python3.6/site-packages/click/core.py", line 764, in __call__ api_1 | return self.main(*args, **kwargs) api_1 | File "/usr/local/lib/python3.6/site-packages/flask/cli.py", line 380, in main api_1 | return AppGroup.main(self, *args, **kwargs) api_1 | File "/usr/local/lib/python3.6/site-packages/click/core.py", line 717, in main api_1 | rv = self.invoke(ctx) api_1 | File "/usr/local/lib/python3.6/site-packages/click/core.py", line 1137, in invoke api_1 | return _process_result(sub_ctx.command.invoke(sub_ctx)) api_1 | File "/usr/local/lib/python3.6/site-packages/click/core.py", line 956, in invoke api_1 | return ctx.invoke(self.callback, **ctx.params) api_1 | File "/usr/local/lib/python3.6/site-packages/click/core.py", line 555, in invoke api_1 | return callback(*args, **kwargs) api_1 | File "/usr/local/lib/python3.6/site-packages/click/decorators.py", line 64, in new_func api_1 | return ctx.invoke(f, obj, *args, **kwargs) api_1 | File "/usr/local/lib/python3.6/site-packages/click/core.py", line 555, in invoke api_1 | return callback(*args, **kwargs) api_1 | File "/usr/local/lib/python3.6/site-packages/flask/cli.py", line 438, in run_command api_1 | use_debugger=debugger, threaded=with_threads) api_1 | File "/usr/local/lib/python3.6/site-packages/werkzeug/serving.py", line 988, in run_simple api_1 | run_with_reloader(inner, extra_files, reloader_interval, reloader_type) api_1 | File "/usr/local/lib/python3.6/site-packages/werkzeug/_reloader.py", line 332, in run_with_reloader api_1 | sys.exit(reloader.restart_with_reloader()) api_1 | File "/usr/local/lib/python3.6/site-packages/werkzeug/_reloader.py", line 176, in restart_with_reloader api_1 | exit_code = subprocess.call(args, env=new_environ, close_fds=False) api_1 | File "/usr/local/lib/python3.6/subprocess.py", line 287, in call api_1 | with Popen(*popenargs, **kwargs) as p: api_1 | File "/usr/local/lib/python3.6/subprocess.py", line 729, in __init__ api_1 | restore_signals, start_new_session) api_1 | File "/usr/local/lib/python3.6/subprocess.py", line 1364, in _execute_child api_1 | raise child_exception_type(errno_num, err_msg, err_filename) api_1 | OSError: [Errno 8] Exec format error: '/api/manage.py'
看起来您的 api / manage.py 没有 shebang ([Wikipedia]:Shebang(Unix)),因此默认(当前)命令处理器( shell- 通常为 bash )正在尝试运行它,(显然)失败。
要解决此问题,请添加一个 shebang (在文件的开头,确保您的编辑器添加了以 Nix 样式结尾的行( \ n , 0x0A , LF )):
默认 Python 安装:
#!/usr/bin/env python
#!/usr/bin/env python3
自定义 Python 安装:
#!/full/path/to/your/custom/python/executable
请注意,您还需要对该文件()具有 执行 权限chmod +x api/manage.py。
chmod +x api/manage.py
例:
> [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q055271912]> > ~/sopr.sh > *** Set shorter prompt to better fit when pasted in StackOverflow (or > other) pages *** > > [prompt]> ls > code0.py code1.py > [prompt]> > [prompt]> cat code0.py > print("This is:", __file__) > > [prompt]> python3 -c "import os, > subprocess;subprocess.Popen(os.path.join(os.getcwd(), > \"code0.py\")).communicate()" > Traceback (most recent call last): > File "<string>", line 1, in <module> > File "/usr/lib/python3.6/subprocess.py", line 709, in __init__ > restore_signals, start_new_session) > File "/usr/lib/python3.6/subprocess.py", line 1344, in _execute_child > raise child_exception_type(errno_num, err_msg, err_filename) > OSError: [Errno 8] Exec format error: > '/cygdrive/e/Work/Dev/StackOverflow/q055271912/code0.py' > [prompt]> > [prompt]> cat code1.py > #!/usr/bin/env python3 > > print("This is:", __file__) > > [prompt]> python3 -c "import os, > subprocess;subprocess.Popen(os.path.join(os.getcwd(), > \"code1.py\")).communicate()" > This is: /cygdrive/e/Work/Dev/StackOverflow/q055271912/code1.py
另一种方法是运行解释后面的文件名,但我不知道如何从做 瓶 -实际上是需要修补 WERKZEUG ( __reloader.py_ : __get_args_for_reloading_ ),但这只是一个蹩脚的解决方法( gainarie )-见下文。
查看@AxelGrytt的答案,结果发现这是一个已知问题:[GitHub]:pallets / werkzeug-0.15.0导致OSError:[Errno 8] Exec格式错误:在Docker for Windows中(hmm,与此同时提交问题(发布后2天):))。
因此,我上面所说的是正确的,但是值得一提的是,还有另一种修复方法:删除文件的 exec 权限:
chmod -x api/manage.py
根据 Werkzeug的 作者,从现在开始, 这是理想的行为 (也适用于 v 0.15.2 ):