我遇到了一些我不理解的事情,并且我设法在下面的脚本中重现了这种情况。
如果我获取脚本,它会失败head: 1: invalid number of lines
。但如果将脚本作为脚本执行,它会成功。
# !/bin/bash
# test.sh
function getline {
local line=$(cat /etc/passwd | cut -d':' -f1 | grep --no-messages -nw "$1" | cut -d':' -f1)
/usr/bin/head -n $line /etc/passwd | tail -n 1
}
# Call the function
getline root
如果有来源则调试输出然后调用 ( set -x
)
+ getline root
++ cat /etc/passwd
++ cut -d: -f1
++ cut -d: -f1
++ grep --colour=always -niw root
+ local 'line=1'
+ tail -n 1
+ /usr/bin/head -n '1' /etc/passwd
/usr/bin/head: 1: invalid number of lines
如果直接执行,则调试输出:
+ /tmp/test.sh
++ getline root
+++ cat /etc/passwd
+++ cut -d: -f1
+++ cut -d: -f1
+++ grep -niw root
++ local line=1
++ /usr/bin/head -n 1 /etc/passwd
++ tail -n 1
root:-:-:-:root:/root:/bin/bash
因此,似乎$line
在第一种情况下,赋值参数被引用,
+ local 'line=1'
vs ++ local line=1
,这似乎会导致不同的结果,这是为什么呢?此外,如果变量line
不是本地的,则引用将移动到变量:++ line='1'
这些结果来自 GNU bash,版本 4.2.46(1)-release(x86_64-redhat-linux-gnu)。
编辑:
明确使用/usr/bin/head
=> 相同的结果。
答案1
grep 有一个别名 always color,它把事情搞砸了,并且可能留下了一些没有显示的转义序列set -x
。
因此,解决这个特定问题的方法是明确执行不带颜色的 grep ... | grep --color=never
,绕过使用别名\
... | \grep ...
。
感谢希优顿为我指明了正确的方向。