我正在尝试创建一个别名以在我的 Cygwin shell 中使用,以确定我当前所在的 Mercurial 管理目录是否有未完成的更改。命令“hg st -m”列出所有修改的文件。不幸的是,它没有根据是否有更改来设置退出值。所以我尝试捕获输出并查看它是否不为空,将其通过“wc -l”进行管道传输并检查是否为-gt 0,但我似乎有一个更大的问题,因为这些行显然没有按照我想要的顺序执行期望他们这样做。
这是我将其归结为:
alias hgfoo='
pwd
echo L1
localChanges="NOT SET YET"
hasLocal="NOT SET YET"
echo "Before: A${localChanges}Z A${hasLocal}Z"
localChanges=`hg st -m`
echo L2
echo "localChanges: A${localChanges}Z"
echo L3
if [ -n "${localChanges}" ] ; then
echo L3
hasLocal="YES"
else
echo L4
hasLocal="NO"
fi
echo L5
echo "RESULTS: A${hasLocal}Z"
echo L6
'
我放入“Ln”echo 语句进行调试。当我通过在发生更改的目录中输入“hgfoo”来运行它时,我看到以下输出:
/d/hg/succession > hgfoo
/d/hg/succession
L1
Before: ANOT SET YETZ ANOT SET YETZ
L2
localChanges: AL2
localChanges: ANOT SET YETZ
L3
L3
L5
RESULTS: AYESZ
L6
M succession-lib\.actionScriptProperties
M succession-lib\src\main\flex\com\workscape\SuccessionConstants.as
M succession-lib\src\main\flex\com\workscape\succession\nomination\tabmodules\BenchStrengthTab.mxml
M succession-lib\src\main\flex\com\workscape\succession\nomination\tabmodules\BenchStrengthTabMediator.as
M succession-lib\src\main\flex\com\workscape\succession\puremvc\controller\StartupSuccession.asZ
L3
L3
L5
RESULTS: AYESZ
L6
当我在没有更改的目录中运行它时,我看到:
/d/hg/employee-profile > hgfoo
/d/hg/employee-profile
L1
Before: ANOT SET YETZ ANOT SET YETZ
L2
localChanges: AL2
localChanges: ANOT SET YETZ
L3
L3
L5
RESULTS: AYESZ
L6Z
L3
L3
L5
RESULTS: AYESZ
L6
即使忘记了比较无法正常工作的事实,在这两种情况下,它似乎都在错误的位置多次运行线路。这真让我抓狂。
有什么线索吗?谢谢。
答案1
这是 bash 别名扩展中长期存在的错误。我可以在带有 bash 3.2.29(1) 的 Debian lenny amd64、带有 4.1.5(1) 的 Debian squeeze i386 和带有 bash 4.1.9(3) 的 Cygwin 1.7.7-1 的 Windows XP 上重现它。
一些实验表明,该错误对别名使用方式的变化非常敏感。hgfoo
或hgfoo :
表现出错误,但{ hgfoo :; }
工作(hgfoo)
正常。使用函数代替别名也可以。
我调查了一下,试图提取一个更小的例子。奇怪的地方似乎源于别名中的换行符。这是一个 bash(3.2.29 或 4.1.9)行为不当的简单示例。这个别名在 Debian lenny 下的 pdksh、ksh93、ash 和 zsh 下按预期工作(根据我对 Single Unix v3 的阅读),即oops
prints foo bar
。
$ alias oops='a=$(echo bar)
> echo foo $a'
$ oops
foo foo echo bar
该错误可能与报告的有关“奇怪的延迟别名”的错误,但讨论重点是续行(反斜杠换行),此处未使用。
无论如何,使用函数!别名适用于单行代码,您只需为命令指定一些默认选项。函数还有一个额外的好处,您可以将参数传递给hg
:
hgfoo () {
localChanges=$(hg st -m "$@")
…
}
1 我最初以为这是一个 Cygwin 错误,但随着AK2指出,这个错误在 Linux 下也发生。
答案2
我让它工作了。确实是反引号引起了问题。我将其重构为
hg st -m | grep -q M
然后检查了 grep 的退出值,它运行良好。