Если «bash <file>» работает, то почему «источник <файл>» выбрасывает ошибку?

У меня есть следующий скрипт:

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

Если я запустил bash /tmp/file, a отражается, но если я запустил source /tmp/file, я получаю:

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

Выход:

[email protected] 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

[email protected] 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

[email protected] tmp]$bash -c "source /tmp/test"
+ bash -c 'source /tmp/test'
++ :
++ echo a
a


[email protected] 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 -o: http://pastebin.com/bsqc8aru

Вывод set: http: //pastebin. ком /S9KpqZAL

declare -fp ничего не производит.

Я думал, что source делает то же самое, что и bash, но вместо запуска нового сеанса скорее выполняется код в текущем. Может кто-нибудь объяснить эту ошибку мне?

Я запускаю bash GNU bash, версия 4.2.53 (1) -release (x86_64-redhat-linux-gnu).

25 голосов | спросил knezi 20 J0000006Europe/Moscow 2016, 12:45:31

1 ответ


74

Я могу воспроизвести ваше поведение, если я с псевдонимом fi:

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

Он работает, когда вы его выполняете, но не удается, когда вы его используете, поскольку псевдонимы недоступны в неинтерактивных оболочках (тип оболочки, которая запускает сценарии оболочки). Как описано в руководстве bash :

  

Псевдонимы не расширяются, если оболочка не является интерактивной, если только   Параметр expand_aliases устанавливается с помощью shopt ( см. Shopt   Builtin ).

Однако, когда вы source что-то, оно запускается в вашей текущей оболочке, которая, поскольку она интерактивна, уже загрузила псевдонимы и поэтому распознается псевдоним fi и разбивает источник.

ответил muru 20 J0000006Europe/Moscow 2016, 14:08:24

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132