【问题标题】:Python sys.argv[1:] not picking up command line optionsPython sys.argv[1:] 没有选择命令行选项
【发布时间】:2011-06-21 01:12:39
【问题描述】:

更新/解决方案:答案如下,from Zack。实际上,问题在于脚本文件 clenotes.cmd 本身的 DOS 行结尾。由于我对各种文件非常感兴趣,所以我删除了整个目录,然后从HERE 重新下载了一个新副本。我像这样在文件上运行了 Zack 的 perl 脚本:

perl -pi.bak -e 's/[ \t\r]+$//' clenotes.cmd

然后我稍微编辑了命令执行,最终的脚本变成了:

CWD=`dirname $0`
JYTHON_HOME="$CWD"
LIB_DIR="$JYTHON_HOME/lib"
NOTES_HOME="/opt/ibm/lotus/notes/"
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$NOTES_HOME
java -cp "$LIB_DIR" -jar "$LIB_DIR/jython.jar" -Djython.home="$CWD/" -Dpython.path="$LIB_DIR:$CWD/ext" -Djava.library.path="$NOTES_HOME" "$LIB_DIR/clenotes/cletes/clenotes.py" "$@"

就是这样——其他一切正常。 clenotes.py 或 clenotes.cfg 无需编辑。非常感谢您坚持这个问题,我猜这个问题很简单。


更新:我正在削减一些代码以使其更具可读性并从帖子中删除不必要的信息。


我正在尝试让Lotus Notes command line 在 Linux 上工作,但在 python 文件中遇到了与 sys.argv[1:] 相关的问题。 windows脚本在这里:

@echo off
@setlocal 
set CWD=%~dp0
set JYTHON_HOME=%CWD%
set LIB_DIR=%JYTHON_HOME%/lib
java -cp %LIB_DIR% -jar %LIB_DIR%/jython.jar -Djython.home=%CWD%  -python.path=%LIB_DIR%;%CWD%/ext %LIB_DIR%/clenotes/clenotes.py  %*

@endlocal

我在变量方面遇到了困难,所以对于 Linux,它看起来像这样:

java -cp ./lib/ -jar ./lib/jython.jar -Djython.home=./ -Dpython.path=./lib:./ext -Djava.library.path=/opt/ibm/lotus/notes/ ./lib/clenotes/clenotes.py $*

我从目录中运行它。无论如何,令我困惑的是它没有选择我从命令行传递的任何选项。 clenotes.cmd --help 结果

No commands specified. Use --help option for usage.

这是应该解析命令行参数的部分:

def main():    

  Output.log("Entering %s v%s" % (PROGRAM_NAME,VERSION),Output.LOGTYPE_DEBUG)
  cliOptions2=[]
  for opt in cliOptions:
    opt2=opt.replace('--','')
    opt2=opt2.replace('!','=')
    cliOptions2.append(opt2)
  opts=[]
  args=[]
  try:
    opts, args = getopt.getopt(sys.argv[1:], '', cliOptions2)

我在 32 位 chroot 环境中的 Arch Linux 64 位上使用 Python 3.1.3。我还能提供什么吗?

以防万一……HERE 是整个 clenotes.py 文件。

此外,根据 cmets 的要求,配置文件(包含帮助消息和可行的选项/参数)为 HERE


更新

经过大量的摆弄,我取得的最佳进展是检查它在 (main) 方法中设置为 opts 和 args 的内容。最令人惊讶的是,当传递一个参数,然后使用print sys.argv 查看它的解析结果时,该选项会在其中出现一个尾随\r。例如:

clenotes.cmd appointments
args is ['appointments\r']

在 Windows 上我做了同样的事情,并且 args 被报告为['appointments']。此外,手动设置args=['appointments'],然后注释掉getopt.getopt 分配值的部分。

最后,我发现当使用多个参数时,其中 n-1 个会被解释和使用,而第 n 个会被忽略。这是一种 的解决方法,因为我实际上可以使用该脚本......但显然它不是首选。如果我想查看今天的约会,我可以执行clenotes.cmd appointments --today --today,它会起作用。 sys.argv 会吐槽:['appointments', '--today', '--today\r']

那么...是什么导致了尾随的\r?我认为这与实际脚本有关。再次注意:

java -cp ./lib/ -jar ./lib/jython.jar -Djython.home=./ -Dpython.path=./lib:./ext -Djava.library.path=/opt/ibm/lotus/notes/ ./lib/clenotes/clenotes.py $*

所以...一堆路径的东西,然后是实际的 python 文件:clenotes.py $*

我从HERE 得到了$*

是接回车吗??

【问题讨论】:

  • 好的,下一步是查看 getopt 的行为是否符合预期。你能告诉我当你在这行之后添加一个print opts, args 时你看到了什么:opts, args = getopt.getopt(sys.argv[1:], '', cliOptions2) 并使用一些有效的选项和命令运行 clenotes.py?
  • 另外,如果你能找出日志文件的位置,你应该通过将配置文件的最后一行更改为write_log: true(或者可能是True——或文件名? -- 我不知道输出是如何工作的。)
  • 我不认为这将有助于解决 当前 问题,但除非在 非常罕见 的情况下不适用,否则您应该使用"$@"(如图所示,包括双引号)而不是 $*,当您想将 shell 脚本的整个参数列表传递给嵌套命令时。
  • "这只是您在名为 clenotes.cmd 的文件中看到的命令。"唔。 cat -v clenotes.cmd 打印什么?
  • 哇哇哇。好吧,我知道出了什么问题。 \r 来自 clenotes.cmd。是 bash(或您拥有的任何 shell)将以该文件结尾的 DOS 行误解为命令的最后一个参数的一部分。尝试在 clenotes.cmd 上执行我在下面建议的 perl 命令。

标签: python linux command-line jython lotus-notes


【解决方案1】:

我认为您的问题是 clenotes.cfg 有 DOS 行尾,Python 会误解。尝试更改clenotes.py这一行

config.readfp(open('%sconfig/clenotes.cfg' % System.getProperty('jython.home')))

阅读

config.readfp(open('%sconfig/clenotes.cfg' % System.getProperty('jython.home'), "rU"))

“rU”告诉 Python,即使它在 Unix 系统上运行,它也应该准备好处理包含 DOS 行结尾的文件。请参阅http://docs.python.org/library/functions.html#open——向下滚动到以“除了标准fopen() 模式...”开头的段落。

(或者你可以运行这个命令:perl -pi.bak -e 's/[ \t\r]+$// clenotes.cfg——这会将它转换为 Unix 行尾。在你的鞋子里,我可能会both。)

(如果上述建议都没有帮助,我接下来会尝试使用上面的 perl 命令点击 clenotes.py 本身。我不明白这可能是什么问题,但如果 \r 字符是不是来自clenotes.cfg.py 文件是唯一合理的剩余来源。)

(编辑:根据您对问题本身的 cmets,我现在认为它是 clenotes.cmd,shell 脚本包装器,需要从 DOS 转换为 Unix 行结尾。)

【讨论】:

  • +1 显而易见。并且始终使用使用适当行尾的 IDE。
  • 是的,我不得不离开,就在我走出门的时候,我意识到 clenotes.cmd 必须是 dos 格式的。但这仍然不能解释为什么选项没有被解析。
  • 我还是会把它归咎于 .cfg 文件中的 DOS 行结尾,直到我们听到不同的声音。
  • @Zack:我复制/粘贴了你的行只是为了确保我没有弄错,但它从第 29 行(我们修改的行)产生了IOError: Unknown open mode:rU。 perl diddy did 改变了 sys.argv 数组的结果,但实际脚本 clenotes.cmd 需要它,该脚本在行尾有尾随 ^Ms。 clenotes.cmd today 现在在 sys.argv 中生成 ['today'] 而不是 ['today\r']。不幸的是, --help 仍然没有被解析。它正在读取参数而不是选项。
  • 哎呀——说得太早了!刚刚再次尝试 --help 并且成功了! --noheader 也是如此。不幸的是,我不在公司的网络中,即使使用 vpn 连接也找不到我的数据库。我将在星期一运行一些命令并重试——如果一切顺利,我认为这是问题所在。我将在公开此命令行的两个位置发布指向此的链接。谢谢大家!!
【解决方案2】:

我将不得不继续寻找 \r 的来源。但与此同时,这个问题变得简单多了。解析 args 后,执行以下操作:

args = [arg.strip() for arg in args]

这将摆脱\r

编辑:但是等等——这只是部分解决方案吗?还是没有正确解析选项?

EDIT2:似乎\r 需要提前剥离。当没有命令时,/r 永远不会被剥离,因为上面只在 getopt 完成后剥离 \r。这对我来说应该很明显——而不是在这里传递sys.argv[1:]

opts, args = getopt.getopt(sys.argv[1:], '', cliOptions2)

先修改

argv = [arg.strip() for arg in sys.argv[1:]]
opts, args = getopt.getopt(argv, '', cliOptions2)

你也可以只做sys.argv[-1] = sys.argv[-1].strip()...但是我的 C 程序员看到它开始觉得有点恶心。可能是不合理的,我知道。

或者按照 Zack 所说的将 clenotes.cmd 转换为 linux 格式——但是,请注意这里的剥离将确保其他人不必再次解决相同的问题。 (另一方面,它有点丑陋,或者至少对于那些没想到会出现此类问题的人来说是神秘的。)

【讨论】:

  • 这太傻了。我在opts,args=getopts.getopts... 行下方添加了您的行。我也(为了它)添加了print sys.argv。结果非常有趣。 1)clenotes.cmd today 现在可以工作了。 2) clenotes.cmd --help 仍然不起作用,除非它后面有另一个选项。 3) 最令人费解的是print sys.argv 的输出是 same 无论我是否有你的arg.strip 行。它总是:['./clenotes.py', 'today\r']\r 那时还在那里!你是对的:它仍然没有选择 --options 除非有一个命令。
  • @Hendy,我对此的新想法见上文。
猜你喜欢
  • 2017-06-14
  • 1970-01-01
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
相关资源
最近更新 更多