bash:如果从源脚本调用或直接执行相同的函数,则会产生不同的结果

bash:如果从源脚本调用或直接执行相同的函数,则会产生不同的结果

我遇到了一些我不理解的事情,并且我设法在下面的脚本中重现了这种情况。

如果我获取脚本,它会失败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 ...

感谢希优顿为我指明了正确的方向。

相关内容