Bash - > Batch + Colon和back / forward-slash使用

时间:2012-10-14 10:24:35

标签: eclipse bash shell batch-file pydev

我正在尝试通过使用在eclipse启动之前运行的批处理脚本来使便携式pyDev自动设置python解释器。为了做到这一点,我遇到了以下bash脚本,但我无法将其翻译为批处理(我很熟悉):

PYTHONPATH=/my/extra/python/modules python /my/eclipse/plugins/org.python.pydev_*/PySrc/interpreterInfo.py 2>/dev/null | sed 's/INS_PATH$//g;s/OUT_PATH$//g;s/^EXECUTABLE:/Executable\\:/g' | tr -d '\n' | cat <(echo -en 'eclipse.preferences.version=1\nINTERPRETER_PATH_NEW=Name\:python\:EndName\:') - <(echo '&&&&&') >/my/workspace/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.python.pydev.prefs

我尝试将其分解以查看正在替换/管道的位置,但这没有意义:

PYTHONPATH= App/Eclipse/plugins/org.python.pydev_*/PySrc/interpreterInfo.py 2> /dev/null 
|sed '  s/ INS_PATH$/ / g; REM Delete all instances of INS_PATH that are at the end of a line
        s/ OUT_PATH$/ / g; REM Delete all instances of OUT_PATH that are at the end of a line
        s/ ^EXECUTABLE:/ Executable\\:/ g REM Replace all instances of "\nEXECUTABLE:" that are at the beginning of a line with "Executable\:"
' 
|tr -d '\n' 
|cat <(echo -en 'eclipse.preferences.version= 1 \n INTERPRETER_PATH_NEW= Name\:python\:EndName\:') - <(echo '&&&&&') 
>/my/workspace/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.python.pydev.prefs

最令人困惑的部分之一是使用冒号并使用'/' vs '\'。 查看配置文件,我看到osgi.framework=file\:plugins/org.eclipse.osgi_3.8.0.v20120529-1548.jar

1 个答案:

答案 0 :(得分:2)

我试图格式化&#34;原创&#34;使其更具可读性。我会尝试解释那里发生的事情:

PYTHONPATH=/my/extra/python/modules \
    python /my/eclipse/plugins/org.python.pydev_*/PySrc/interpreterInfo.py 2>/dev/null |
    sed '
        s/INS_PATH$//g;
        s/OUT_PATH$//g;
        s/^EXECUTABLE:/Executable\\:/g
    ' |
    tr -d '\n' |
    cat \
        <(
            echo -en 'eclipse.preferences.version=1\nINTERPRETER_PATH_NEW=Name\:python\:EndName\:'
        ) \
        - \
        <(echo '&&&&&') \
     >/my/workspace/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.python.pydev.prefs

现在,让我们逐节了解这一点。为了完整起见,我会仔细检查一切,包括我希望你已经知道的部分。

PYTHONPATH=/my/extra/python/modules \

这是设置变量PYTHONPATH,从上下文我希望告诉python在哪里寻找模块。因为我们在相同的&#34;行&#34;中指定它。作为一个命令,有两件事情发生:

  1. 变量自动导出到环境
  2. 该变量仅针对正在运行的单个命令设置(即:只是&#34;第一个&#34;命令,而不是整个管道,并且它不会在shell中运行&#39;的环境供以后的命令使用)
  3. 接下来是主命令:

     python /my/eclipse/plugins/org.python.pydev_*/PySrc/interpreterInfo.py 2>/dev/null |
    

    这里&#34; python&#34;运行解释器,并传递interpreterInfo.py脚本来执行。

    _*表示我们没有指定我们想要的org.python.pydev的特定版本(假设只找到一个版本,并且所有版本的行为都相似)。

    2>/dev/null表示stderr上的任何输出(通常是管道传输错误和调试信息)都将被忽略(通过管道输送到任何地方)。

    现在它的肉:

    sed '
        s/INS_PATH$//g;
        s/OUT_PATH$//g;
        s/^EXECUTABLE:/Executable\\:/g
    ' |
    

    这有三件事。前两个是相似的:INS_PATHOUT_PATH从行的末尾删除。接下来,以及您询问的第一部分,:字符将替换为\:。如果\\是目标,为什么双\:?这主要归功于迂腐。虽然\:不是有效的转义序列,但大多数sed会将其解释为文字\标记Escape Sequence的开头,因此规范的指定方式您希望sed输出文字\是将其指定为\\。因此,对于序列\:,它被指定为\\:

    每个替换命令末尾的/g表示&#34;全局替换&#34;,即:每次找到匹配时,而不仅仅是第一次。

    下一行很简单:

    tr -d '\n' |
    

    这将删除输出中的所有换行符。如果我理解正确,则会在一行上生成\:个分隔的路径列表。

    返回可能需要解释的部分:

    cat \
        <(
            echo -en 'eclipse.preferences.version=1\nINTERPRETER_PATH_NEW=Name\:python\:EndName\:'
        ) \
        - \
        <(echo '&&&&&') \
     >/my/workspace/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.python.pydev.prefs
    

    要立刻完成所有这一切。让我们总结一下:

    cat input-one input-two input-n > output
    

    cat将多个输入组合(&#34;连接&#34;)到单个输出中。这实际上是cat命令的预期用途,尽管您可能会看到它更常用于输出单个输入,例如:cat input-one

    <( some-command )
    

    运行some-command并将其输出重定向到File Descriptor,其路径(/dev/fd/N)被用作<( ... )最初所在的上下文中的参数。示例:cat <( echo foo )将运行类似于cat /dev/fd/64echo foo的命令,将echo foo的输出重定向到文件描述符64,以便按{{1}读取}}。输出为cat,就像您直接运行foo一样。

    现在,将这两件事结合起来:

    echo

    这会将cat <( some-command ) some-input <( some-other-command ) 的输出,some-command的内容和some-input的输出合并为一个流。在您正在使用的脚本中,这些都被合并到一个输出文件中。

    那么实际为这个输出构建的内容呢?让我们逐行看一下:

    some-other-command

    这输出文字:

    <(
        echo -en 'eclipse.preferences.version=1\nINTERPRETER_PATH_NEW=Name\:python\:EndName\:'
    )
    

    eclipse.preferences.version=1 INTERPRETER_PATH_NEW=Name\:python\:EndName\: 表示&#34;解释反斜杠转义序列&#34;,因此echo -e扩展为换行符。 \n表示&#34;不使用换行符结束输出&#34;,所以下一步是同一行的一部分。在这种情况下,这意味着接下来连接的任何内容都将成为echo -n行的一部分。

    INTERPRETER_PATH_NEW=

    - 是&#34;从标准输入&#34;读取的简写,如果您自行运行-,则默认为。许多命令使用这种速记,但对于那些没有,另一种指定方式是cat。这意味着&#34;读取管道输入到此命令的内容,即:/dev/stdin的输出,它本身默认为读取tr的输出,默认为读取输出sed

    python

    这会结束包含五个<(echo '&&&&&') 字符和换行符的流。我实际上并不知道这个的原因,所以也许有人可以发表评论来填补我。

    &

    最后一步,所有输出都会(通过>/my/workspace/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.python.pydev.prefs 符号)重定向到文件>

    通过大概了解正在发生的事情,现在是时候回答您所询问的麻烦细节了:

    为什么所有org.python.pydev.prefs个字符?

    嗯,就像我们在sed中转发\一样,我们也在\文件中转义:.prefs文件中的\:似乎意味着&#34;文字.prefs&#34;与sed中的:指定文字\\的方式相同。

    \字符怎么样?

    /是UNIX系统中的目录分隔符(包括现代Mac OS,即OSX)。在Windows系统上,使用/。在许多语言中,如上所述,\也用作转义字符,因此要指定文字\,您可能需要将其写为\。对此没有硬性规定。一些知道该问题的跨平台语言也允许\\在Windows上用作目录分隔符。

    我希望能够解决问题。如果还有其他需要解释的地方,请告诉我,我会尝试编辑我的答案以添加其他信息。