Bash-->批处理 + 冒号和反斜杠/正斜杠使用



我正在尝试使用在 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=1nINTERPRETER_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

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

我试图格式化"原始"以使其更具可读性。我将尝试解释从那里发生的事情:

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=1nINTERPRETER_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 在哪里寻找模块。因为我们在与命令相同的"行"中指定它,所以会发生两件事:

  1. 变量会自动导出到环境
  2. 该变量仅针对正在运行的单个命令设置(即:仅"第一个"命令,而不是整个管道,并且它不会在 shell 的环境中供后续命令使用)

接下来,主命令:

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

这里运行"python"解释器,并传递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会将其解释为文字标记转义序列的开始,因此指定您希望sed输出文字的规范方法是将其指定为\。因此,对于序列:,它被指定为\:

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

下一行很简单:

tr -d 'n' |

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

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

cat 
<(
echo -en 'eclipse.preferences.version=1nINTERPRETER_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将多个输入组合("连接")为单个输出。这实际上是cat命令的预期用途,尽管您可能会看到它更常用于输出单个输入,例如:cat input-one

<( some-command )

运行some-command并将其输出重定向到文件描述符中,其路径 (/dev/fd/N) 在<( ... )最初所在的上下文中用作参数传递。例如:cat <( echo foo )会运行一个类似于cat /dev/fd/64echo foo的命令,将echo foo的输出重定向到文件描述符64,供cat读取。输出是foo,就像直接运行echo一样。

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

cat <( some-command ) some-input <( some-other-command )

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

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

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

这将输出文本:

eclipse.preferences.version=1
INTERPRETER_PATH_NEW=Name:python:EndName:

echo -e的意思是"解释反斜杠转义序列",因此n扩展为换行符。echo -n表示"不要以换行符结束输出",因此接下来的任何内容都是同一行的一部分。在这种情况下,这意味着接下来连接的任何内容都将成为INTERPRETER_PATH_NEW=行的一部分。

-

-是"从标准输入读取"的简写,如果您单独运行cat,这是默认值。许多命令都使用此速记,但对于那些不使用的命令,另一种指定此方法的方法是/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文件中转义:.prefs文件中的:似乎意味着"文字:",就像 sed 中的\指定文字一样。

/角色呢?

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

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

相关内容

  • 没有找到相关文章

最新更新