如果“ bash <文件>”有效,为什么“源<文件>”抛出错误?


26

我有以下脚本:

#!/bin/bash
set -x
if :; then
    echo a
fi

如果我运行bash /tmp/filea则会被回显,但是如果我运行source /tmp/file,则会得到:

bash: /tmp/test: line 6: syntax error: unexpected end of file

输出:

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

命令shopt -p和的输出set -ohttp : //pastebin.com/bsqc8aru

输出sethttp : //pastebin.com/S9KpqZAL

declare -fp 什么都不产生。

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

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


1
不,这是完整的代码。换行符是0a。
knezi

2
@Rahul Unix换行符的十六进制代码
PSkocik,2016年

2
$BASH_ENV集合吗?
roaima

2
@PSkocik真的很奇怪。bash -c“源/ tmp / test”有效。
knezi

5
啊哈!请补充说明它适用bash -c于您的问题。然后,向我们展示您~/.bashrc文件的内容,可能是有些东西在搞砸。
terdon

Answers:


75

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

$ alias fi=:
+ alias fi=:
$ . ./test
+ . ./test
++ set -x
bash: ./test: line 6: syntax error: unexpected end of file

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

如果外壳不是交互式的,则别名不会扩展,除非 expand_aliases使用设置外壳选项shopt(请参见The Shopt Builtin)。

但是,当您执行source某些操作时,它将在您当前的外壳程序中运行,因为它是交互式的,因此已经加载了别名,因此fi可以识别别名并中断源。


16
你是完全正确的。我已经设置了:alias fi ='find -type f | xargs grep -H'。
knezi

7
alias现在摆脱它!:)
马克·斯图尔特

9
令我惊讶的是,任何人都设法弄清了这样一个晦涩的问题。干得好,先生。
MathematicalOrchid

6
@MathematicalOrchid我怀疑有东西别名(因为交互式shell),set由输出排除,和alias if='foo "'(尾公开报价给了一个错误关于失踪报价,所以最后一个选项是别名fi
穆鲁
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.