Eğer "bash <dosya>" çalışıyorsa, neden "kaynak <dosya>" hata atıyor?


26

Aşağıdaki betiğe sahibim:

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

Koşarsam bash /tmp/file, ayankılandı, ama ben çalıştırırsanız source /tmp/file, alıyorum:

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

Çıktı:

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

Komutların çıktısı shopt -pve set -o: http://pastebin.com/bsqc8aru

Çıktı set: http://pastebin.com/S9KpqZAL

declare -fp hiçbir şey üretmez.

Ben sourcede aynı şeyi düşündüm bash, fakat yeni oturum başlatmak yerine o anki koddaki kodu çalıştırıyoruz. Birisi bu hatayı bana açıklayabilir mi?

Bash GNU bash, sürüm 4.2.53 (1) - tekrar yayın (x86_64-redhat-linux-gnu) kullanıyorum.


1
Hayır, bütün kod bu. Yeni satırlar 0a'dır.
knezi

2
@Rix, Unix
kalıbı

2
$BASH_ENVseti?
roaima

2
@PSkocik bu gerçekten garip. bash -c "kaynak / tmp / test" çalışır.
knezi

5
Ah-ha! Lütfen bash -csorunuza uygun olduğunu ekleyin. Ardından, bize ~/.bashrcdosyanızın içeriğini gösterin , muhtemelen bir şeyleri mahvedecek bir şey var.
terdon

Yanıtlar:


75

Ben takma iseniz davranışınızı çoğaltabilirim fi:

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

Çalıştırdığınızda çalışır, ancak takma ad etkileşimli olmayan kabuklarda (kabuk komut dosyalarını çalıştıran kabuk türü) kullanılamadığından kaynak olduğunda başarısız olur. Bash kılavuzunda açıklandığı gibi :

Kabuk etkileşimli olmadığında, expand_aliaseskabuk seçeneği kullanılarak ayarlanmadıkça takma adlar genişletilmez shopt(bkz. The Shopt Builtin ).

Bununla birlikte, bir sourceşey olduğunda , şu anki kabuğunuzda çalıştırılır, çünkü etkileşimlidir, takma adları zaten yükler ve bu nedenle fitakma ad tanınır ve kaynağı bozar.


16
Tamamen haklısın. Ayarladım: alias fi = 'find -type f | xargs grep -H '.
knezi

7
Ondan aliasşimdi kurtul ! :)
Mark Stewart

9
Kimsenin böyle karanlık bir problemi çözebildiğinden şaşırdım. Aferin efendim.
Matematiksel

6
@MathematicalOrchid birşeyin takma olduğundan (etkileşimli kabuk nedeniyle) setçıktının dışlandığından ve alias if='foo "'(açık bir açık teklifin eksik teklifle ilgili bir hata verdiğinden ve bu nedenle son seçenek diğer fi
isimlendirmeydi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.