Se "bash <file>" funziona, perché "source <file>" genera un errore?


26

Ho il seguente script:

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

Se corro bash /tmp/file, aviene ripetuto, ma se corro source /tmp/file, ottengo:

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

L'output:

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

Output dei comandi shopt -pe set -o: http://pastebin.com/bsqc8aru

Uscita di set: http://pastebin.com/S9KpqZAL

declare -fp non produce nulla.

Ho pensato che sourcefa lo stesso di bash, ma invece di iniziare una nuova sessione esegue il codice in quello corrente. Qualcuno può spiegarmi questo errore?

Corro bash GNU bash, versione 4.2.53 (1) -release (x86_64-redhat-linux-gnu).


1
No, questo è l'intero codice. Newline sono 0a.
knezi,

2
@Rahul il codice esadecimale del carattere di avanzamento riga Unix
PSkocik,

2
È il $BASH_ENVset?
roaima,

2
@PSkocik è davvero strano. bash -c "source / tmp / test" funziona.
knezi,

5
Ah-ah! Si prega di aggiungere che funziona con la bash -ctua domanda. Quindi, mostraci il contenuto del tuo ~/.bashrcfile, probabilmente c'è qualcosa che sta rovinando le cose.
terdon

Risposte:


75

Posso riprodurre il tuo comportamento se alias fi:

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

Funziona quando lo si esegue ma non riesce quando lo si utilizza perché gli alias non sono disponibili nelle shell non interattive (il tipo di shell che esegue script di shell). Come spiegato nel manuale di bash :

Gli alias non vengono espansi quando la shell non è interattiva, a meno che l' expand_aliasesopzione shell non sia impostata usando shopt(vedi The Shopt Builtin ).

Tuttavia, quando si sourceesegue qualcosa, viene eseguito nella shell corrente che, poiché è interattiva, ha già caricato gli alias e quindi l' fialias viene riconosciuto e interrompe l'approvvigionamento.


16
Hai perfettamente ragione. Ho impostato: alias fi = 'find -type f | xargs grep -H '.
knezi,

7
Sbarazzati di quello aliasora! :)
Mark Stewart,

9
Sono stupito che qualcuno sia riuscito a capire un problema così oscuro. Ben fatto signore.
MathematicalOrchid,

6
@MathematicalOrchid Ho sospettato che qualcosa fosse aliasato (a causa della shell interattiva), setera escluso dall'output e alias if='foo "'(una citazione aperta finale ha dato un errore sulla citazione mancante, e quindi l'ultima opzione era aliasing fi.
Muru
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.