如果“bash <file>”有效,为什么“source <file>”会抛出错误?

kne*_*ezi 28 bash shell-script

我有以下脚本:

#!/bin/bash
set -x
if :; then
    echo a
fi
Run Code Online (Sandbox Code Playgroud)

如果我运行bash /tmp/file,a被回显,但如果我运行source /tmp/file,我得到:

bash: /tmp/test: line 6: syntax error: unexpected end of file
Run Code Online (Sandbox Code Playgroud)

输出:

knezi@holly tmp]$set -x; source /tmp/test; set +x
+ source /tmp/test
++ set -x
bash: /tmp/test: line 6: syntax error: unexpected end of file
+ set +x

knezi@holly tmp]$set -x; command source /tmp/test; set +x
+ set -x
+ command source /tmp/test
+ source /tmp/test
++ set -x
bash: /tmp/test: line 6: syntax error: unexpected end of file
+ set +x

knezi@holly tmp]$bash -c "source /tmp/test"
+ bash -c 'source /tmp/test'
++ :
++ echo a
a


knezi@holly tmp]$od -c /tmp/test
0000000   #   !   /   b   i   n   /   b   a   s   h  \n   s   e   t    
0000020   -   x  \n   i   f       :   ;       t   h   e   n  \n  \t   e
0000040   c   h   o       a  \n   f   i  \n
0000051
Run Code Online (Sandbox Code Playgroud)

命令的输出shopt -pset -ohttp : //pastebin.com/bsqc8aru

输出sethttp : //pastebin.com/S9KpqZAL

declare -fp 什么也不产生。

我认为这source与 相同bash,但不是启动新会话而是运行当前会话中的代码。谁能向我解释这个错误?

我运行 bash GNU bash,版本 4.2.53(1)-release (x86_64-redhat-linux-gnu)。

mur*_*uru 78

如果我使用别名,我可以重现您的行为fi

$ alias fi=:
+ alias fi=:
$ . ./test
+ . ./test
++ set -x
bash: ./test: line 6: syntax error: unexpected end of file
Run Code Online (Sandbox Code Playgroud)

它在您执行时有效,但在您获取时失败,因为别名在非交互式 shell(运行 shell 脚本的 shell 类型)中不可用。如bash 手册中所述

当 shell 不是交互式时,别名不会被扩展,除非 expand_aliasesshell 选项是使用设置的shopt(参见The Shopt Builtin)。

但是,当您执行source某些操作时,它会在您当前的 shell 中运行,因为它是交互式的,因此已经加载了别名,因此fi别名被识别并破坏了来源。

  • 你是完全正确的。我已经设置: alias fi='find -type f | xargs grep -H '. (16认同)
  • 我很惊讶有人设法解决了这样一个晦涩的问题。干得好,先生。 (9认同)
  • 立即摆脱那个“别名”!:) (7认同)
  • @MathematicalOrchid 我怀疑某些东西是别名(因为交互式 shell),输出排除了 `set`,以及 `alias if='foo "'`(尾随的开引号给出了关于缺少引号的错误,以及所以最后一个选项是别名`fi`。 (6认同)