【问题标题】:'cleartool find -print' inside Python3 'subprocess.check_output' returns empty stringPython3 'subprocess.check_output' 中的'cleartool find -print' 返回空字符串
【发布时间】:2013-07-10 13:42:55
【问题描述】:

我正在尝试使用 Python 子进程运行以下命令

/usr/atria/bin/cleartool find <path> -follow -name '*.elf' -version "lbtype(CXC1111-111)" -print

代码sn-p:

cmd = [clt, 'find', path, '-follow', '-name', '\"*.elf\"', '-version', lb, "-print"]
try:         
    output = subprocess.check_output(cmd)

    print("--%s--" % output)
    print("===DONE===")
except subprocess.CalledProcessError as e:
    print("CALLEDPROCESSERROR")
    print(e)
except subprocess.TimeoutExpired as e:
    print(e)

运行sn-p后的o/p

--b''--

===DONE===

cleartool find 命令在 shell 上执行时,会打印文件名

理想情况下,python 脚本输出应该打印文件名。 有什么想法会出错吗?

【问题讨论】:

    标签: python subprocess clearcase


    【解决方案1】:

    默认情况下,subprocess.Popen 具有 shell=Falsecheck_output 函数将它的参数传递给Popen,所以你也在这里得到shell=False。在不调用 shell 的情况下,每个参数都会未经解释地传递给cleartool。当您从 shell 运行命令时:

    cleartool find ... -name '*.elf' -version "lbtype(CXC1111-111)" ...
    

    (剪掉一些位以使其更适合窗口),单引号和双引号被外壳剥离,因此cleartool 只得到*.elflbtype(CXC1111-111)。这些是您需要通过shell=False 传递的字节序列。 (保留shell=False 可能是最好的;如果将其设置为True,则必须将命令粘贴到单个字符串中并引用shell 元字符。)

    【讨论】:

    • 很好,比我自己的回答更具体。所以+1。
    • 您对 cleartool 和 shell 的解释让我很清楚。感谢您的详细解释。
    【解决方案2】:

    我想我找到了问题所在。

    在解决之前,这是我的 lb 和 cmd 的样子

    lb = '\"lbtype(%s-%s)\"' % (tmp_prod_no, rev)
    cmd = [clt, 'find', lm_path, '-follow', '-name', '\"*.elf\"', '-version', lb, "-print"]
    

    \" 标签是问题的罪魁祸首 经过以下修改(lb 和 *.elf),它工作正常

    lb = 'lbtype(%s-%s)' % (tmp_prod_no, rev)
    cmd = [clt, 'find', lm_path, '-follow', '-name', '*.elf', '-version', lb, "-print"]
    

    有人能解释一下子进程如何处理命令中的引号吗? 这是我尝试过的不同组合和错误

    案例 1 - lb 和 elf 的双引号

    lb = '\"lbtype(%s-%s)\"' % (tmp_prod_no, rev)
    cmd = [clt, 'find', lm_path, '-follow', '-name', '\"*.elf\"', '-version', lb, "-print"]
    
    o/p:
    --b''--
    ===DONE===
    

    案例 2 - elf 的双引号

    lb = 'lbtype(%s-%s)' % (tmp_prod_no, rev)
    cmd = [clt, 'find', lm_path, '-follow', '-name', '\"*.elf\"', '-version', lb, "-print"]    
    
    o/p:
    cleartool: Error: Syntax error in query (near character 1).
    cleartool: Error: Invalid query: ""lbtype(CXC1727075-R78A12)""
    cleartool: Warning: Skipping   \vobs/cello/babs/control_test_dm/jpre_test_lm/bin/jpre_test.ppc.elf".
    CALLEDPROCESSERROR
    Command '['/usr/atria/bin/cleartool', 'find',   '/vobs/cello/babs/control_test_dm/jpre_test_lm', '-follow', '-name', '*.elf', '-version', '"lbtype(CXC1727075-R78A12)"', '-print']' returned non-zero exit status 1
    

    案例 3 - 没有双引号给出正确答案

    lb = 'lbtype(%s-%s)' % (tmp_prod_no, rev)
    cmd = [clt, 'find', lm_path, '-follow', '-name', '*.elf', '-version', lb, "-print"]
    
    o/p:
    --b'\vobs\asd\asd\adasd'--
    ===DONE===
    

    为什么 clearcase 在案例 2 中抱怨 lbtype 而在案例 1 中却没有。

    【讨论】:

      【解决方案3】:

      正如我在“cleartool find”先决条件中提到的,find 必须从 ClearCase 视图(快照或动态)中执行;

      您需要确保 Python 子进程:

      • 保持当前路径
      • 在该进程中安装了 vob(如果您使用的是动态视图)。

      torek 提到了in the comments 一个更简单的问题原因:

      各种子流程调用的默认值为shell=False

      his answer


      如果您的路径(在 shell 上)是 /vobs,则尤其如此:这仅对已设置的视图有效,该视图会产生自己的进程。请参阅“Python and ClearCase setview”了解更多信息。
      它也不允许像 'clt' 这样的别名工作('cleartool' 可能工作,'clt' 不行:请参阅 "Clearcase running commands from a script (error: Bad phone number)" 作为示例)

      使用动态视图的完整路径在动态视图中尝试:

      /view/aView/vobs/aVob/...
      

      一个好的测试是让你的 Python 脚本先做:

      • cwd(当前工作目录)的打印件
      • cleartool lsvob(查看,如果您在动态视图中,如果those vobs are still mounted 在 python 子进程中)。

      【讨论】:

      • 我用下面的行替换了 cmd 并且我得到了正确的输出 cmd = [clt, "ls", vobfile] 所以我相信与 vlearcase 视图相关的设置应该没问题。
      • @Hemanth 或 cleartool find 以某种方式在 stderr 而不是 stdout 上打印?
      • 关于 cleartool 的所有限制,您是对的(当然),但这种情况下的问题要简单得多。 :-) 各种subprocess 调用的默认值为shell=False
      • 顺便说一句,在以前的 $orkplace 中,我有一个副项目,试图为 ClearCase 编写类似 cvsps 的东西。我在这里找到了很多关于 CC 的信息,非常有用。 (副项目从来没有那么远,现在它是“以前的 $orkplace”。但是,仍然从多站点 zippy 合并中追踪原始签入,呃。)
      • @torek 谢谢。有趣的是,我负责编写一个 ClearCase 到 Git 的导入工具。该工作区也称为“以前的”;)
      猜你喜欢
      • 1970-01-01
      • 2018-08-23
      • 2020-01-27
      • 2020-07-11
      • 2015-05-25
      • 2011-05-09
      • 1970-01-01
      • 2012-07-20
      • 2011-12-15
      相关资源
      最近更新 更多