【问题标题】:Python subprocess call precompiled javaPython子进程调用预编译java
【发布时间】:2015-06-01 08:00:58
【问题描述】:

这适用于 windows 命令行:

c:\mallet\bin\mallet run

我试过了

subprocess.call(['c:\mallet\bin\mallet', 'run'])

得到一个错误

WindowsError: [Error 2] The system cannot find the file specified

我试过了

subprocess.call(['c:/mallet/bin/mallet', 'run'])

并得到错误

WindowsError: [Error 193] %1 is not a valid Win32 application

我必须将什么传递给 subprocess.call()?

为了完整起见,我想传递的完整命令是:

bin\mallet run cc.mallet.topics.tui.DMRLoader texts.txt features.txt instance.mallet

我的模糊想法是,这是我以某种方式调用的预编译的 java 类,但我不太明白我在这里做什么。

这是文件夹bin中的两个槌文件:

mallet.bat

@echo off

rem This batch file serves as a wrapper for several
rem  MALLET command line tools.

if not "%MALLET_HOME%" == "" goto gotMalletHome

echo MALLET requires an environment variable MALLET_HOME.
goto :eof

:gotMalletHome

set MALLET_CLASSPATH=%MALLET_HOME%\class;%MALLET_HOME%\lib\mallet-deps.jar
set MALLET_MEMORY=1G
set MALLET_ENCODING=UTF-8

set CMD=%1
shift

set CLASS=
if "%CMD%"=="import-dir" set CLASS=cc.mallet.classify.tui.Text2Vectors
if "%CMD%"=="import-file" set CLASS=cc.mallet.classify.tui.Csv2Vectors
if "%CMD%"=="import-smvlight" set CLASS=cc.mallet.classify.tui.SvmLight2Vectors
if "%CMD%"=="train-classifier" set CLASS=cc.mallet.classify.tui.Vectors2Classify
if "%CMD%"=="train-topics" set CLASS=cc.mallet.topics.tui.Vectors2Topics
if "%CMD%"=="infer-topics" set CLASS=cc.mallet.topics.tui.InferTopics
if "%CMD%"=="estimate-topics" set CLASS=cc.mallet.topics.tui.EstimateTopics
if "%CMD%"=="hlda" set CLASS=cc.mallet.topics.tui.HierarchicalLDATUI
if "%CMD%"=="prune" set CLASS=cc.mallet.classify.tui.Vectors2Vectors
if "%CMD%"=="split" set CLASS=cc.mallet.classify.tui.Vectors2Vectors
if "%CMD%"=="bulk-load" set CLASS=cc.mallet.util.BulkLoader
if "%CMD%"=="run" set CLASS=%1 & shift

if not "%CLASS%" == "" goto gotClass

echo Mallet 2.0 commands: 
echo   import-dir        load the contents of a directory into mallet instances (one per file)
echo   import-file       load a single file into mallet instances (one per line)
echo   import-svmlight   load a single SVMLight format data file into mallet instances (one per line)
echo   train-classifier  train a classifier from Mallet data files
echo   train-topics      train a topic model from Mallet data files
echo   infer-topics      use a trained topic model to infer topics for new documents
echo   estimate-topics   estimate the probability of new documents given a trained model
echo   hlda              train a topic model using Hierarchical LDA
echo   prune             remove features based on frequency or information gain
echo   split             divide data into testing, training, and validation portions
echo Include --help with any option for more information


goto :eof

:gotClass

set MALLET_ARGS=

:getArg

if "%1"=="" goto run
set MALLET_ARGS=%MALLET_ARGS% %1
shift
goto getArg

:run

java -Xmx%MALLET_MEMORY% -ea -Dfile.encoding=%MALLET_ENCODING% -classpath %MALLET_CLASSPATH% %CLASS% %MALLET_ARGS%

:eof

mallet

#!/bin/bash


malletdir=`dirname $0`
malletdir=`dirname $malletdir`

cp=$malletdir/class:$malletdir/lib/mallet-deps.jar:$CLASSPATH
#echo $cp

MEMORY=1g

JAVA_COMMAND="java -Xmx$MEMORY -ea -Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -classpath $cp"

CMD=$1
shift

help()
{
cat <<EOF
Mallet 2.0 commands: 

  import-dir         load the contents of a directory into mallet instances (one per file)
  import-file        load a single file into mallet instances (one per line)
  import-svmlight    load SVMLight format data files into Mallet instances
  train-classifier   train a classifier from Mallet data files
  classify-dir       classify data from a single file with a saved classifier
  classify-file      classify the contents of a directory with a saved classifier
  classify-svmlight  classify data from a single file in SVMLight format
  train-topics       train a topic model from Mallet data files
  infer-topics       use a trained topic model to infer topics for new documents
  evaluate-topics    estimate the probability of new documents under a trained model
  hlda               train a topic model using Hierarchical LDA
  prune              remove features based on frequency or information gain
  split              divide data into testing, training, and validation portions

Include --help with any option for more information
EOF
}

CLASS=

case $CMD in
    import-dir) CLASS=cc.mallet.classify.tui.Text2Vectors;;
    import-file) CLASS=cc.mallet.classify.tui.Csv2Vectors;;
        import-svmlight) CLASS=cc.mallet.classify.tui.SvmLight2Vectors;;
    train-classifier) CLASS=cc.mallet.classify.tui.Vectors2Classify;;
        classify-dir) CLASS=cc.mallet.classify.tui.Text2Classify;;
        classify-file) CLASS=cc.mallet.classify.tui.Csv2Classify;;
        classify-svmlight) CLASS=cc.mallet.classify.tui.SvmLight2Classify;;
    train-topics) CLASS=cc.mallet.topics.tui.Vectors2Topics;;
    infer-topics) CLASS=cc.mallet.topics.tui.InferTopics;;
    evaluate-topics) CLASS=cc.mallet.topics.tui.EvaluateTopics;;
    hlda) CLASS=cc.mallet.topics.tui.HierarchicalLDATUI;;
    prune) CLASS=cc.mallet.classify.tui.Vectors2Vectors;;
    split) CLASS=cc.mallet.classify.tui.Vectors2Vectors;;
    bulk-load) CLASS=cc.mallet.util.BulkLoader;;
    run) CLASS=$1; shift;;
    *) echo "Unrecognized command: $CMD"; help; exit 1;;
esac

$JAVA_COMMAND $CLASS $*

【问题讨论】:

  • 我在 windows 命令行中输入了assoc c:\mallet\bin\mallet,返回的是File association not found for extension c:\mallet\bin\mallet 我也尝试了/,结果相同。
  • 您是否尝试过答案中的任何建议?
  • 问题是c:\mallet\bin\mallet是不可执行的,c:\mallet\bin\mallet到底是什么?如果是java文件为什么不用java运行呢?
  • 很遗憾我不知道。名为mallet的文件夹中有两个文件:mallet.bat(以@echo off开头)和mallet(以#!/bin/bash开头)。
  • 这是在 Windows 上?

标签: java python subprocess call


【解决方案1】:

当您调用没有扩展名的程序时,Windows shell 将尝试几个标准扩展名(.BAT.EXE、...)以便猜测您尝试调用的文件.

如果你想在没有 shell 的情况下执行你的程序来执行查找阶段,你需要传递你试图执行的批处理的全名——包括。 .BAT 扩展:

subprocess.call(['c:/mallet/bin/mallet.bat', 'run'])
【解决方案2】:

确保将shell = True 参数传递给subprocess.call()。但是,它会带来安全问题,因此请务必查看文档并了解其工作原理。

subprocess.call(['c:/mallet/bin/mallet', 'run'], shell = True)

此外,当使用字符串来识别包含反斜杠的路径时,请将其设为原始字符串 (r"This is a raw string!"),这样它就不会实现其他任何内容(例如换行符)。

如果我的上述建议不起作用,我只能做两件事:

  1. 您尝试执行的文件可能不是应用程序文件(.exe 文件)。我不使用 Windows,所以我不确定这个,但它可能是一种可能性。
  2. 文件中的某些内容已损坏或类似情况。

subprocess.call() docs

subprocess.call() Security Issues

【讨论】:

  • 感谢您的建议。您知道使用 shell=True 会带来什么样的安全问题吗?我认为木槌不太可能构成安全风险。我在字符串前面尝试了r,但得到了相同的WindowsError: [Error 193] %1 is not a valid Win32 application 错误。
  • shell = True 施加的唯一安全问题是命令是否基于外部输入。我将设置指向文档的链接。不过,我怀疑在这种情况下您无论如何都必须担心它;)
  • 您的答案有效,我将在一两天内接受它,但想听听是否有人建议如何让subprocess.call() 在没有shell = True 的情况下工作。
  • 当然没问题。我可能应该指出,您将始终需要shell = True。在其他函数中,例如os.system,就像处理subprocess.callshell = True 参数一样。
【解决方案3】:

嗯,问题可能出在反斜杠上。

来自他们的docs

反斜杠 (\) 字符用于转义字符 否则有特殊含义,例如换行符,反斜杠本身, 或引号字符。

所以你可能应该这样做:

subprocess.call(['c:\\mallet\\bin\\mallet', 'run'])

【讨论】:

  • OP 指出他们尝试了正斜杠,它的解释方式与反斜杠相同,不需要转义。
  • 感谢您的建议。我试过并得到了WindowsError: [Error 193] %1 is not a valid Win32 application 错误。
猜你喜欢
  • 2014-09-04
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多