หาก“ bash <file>” ใช้งานได้เหตุใด“ แหล่งที่มา <file>” จึงเกิดข้อผิดพลาดขึ้น


26

ฉันมีสคริปต์ต่อไปนี้:

#!/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

ผลลัพธ์:

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

ผลลัพธ์ของset: http://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 linefeed
PSkocik

2
เป็น$BASH_ENVชุดหรือไม่
roaima

2
@PSkocik ที่แปลกจริง ๆ bash -c "source / tmp / test" ทำงาน
knezi

5
อ๋อ! โปรดเพิ่มว่าใช้ได้กับbash -cคำถามของคุณ จากนั้นแสดงเนื้อหาของ~/.bashrcไฟล์ของคุณให้เราเห็นอาจมีบางอย่างที่ทำให้สกรูของขึ้น
terdon

คำตอบ:


75

ฉันสามารถทำซ้ำพฤติกรรมของคุณถ้าฉันนามแฝงfi:

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

มันทำงานได้เมื่อคุณรันมัน แต่ล้มเหลวเมื่อคุณมามันเพราะนามแฝงไม่สามารถใช้งานได้ในเชลล์แบบไม่โต้ตอบ (ชนิดของเชลล์ที่รันเชลล์สคริปต์) ตามที่อธิบายไว้ในคู่มือทุบตี :

นามแฝงจะไม่ถูกขยายเมื่อเชลล์ไม่ได้ทำงานยกเว้นว่า expand_aliasesมีการตั้งค่าตัวเลือกของเชลล์shopt(ดูThe Shopt Builtin )

อย่างไรก็ตามเมื่อคุณมีsourceบางอย่างมันจะถูกเรียกใช้ในเชลล์ปัจจุบันของคุณซึ่งเนื่องจากมันเป็นแบบโต้ตอบได้โหลดนามแฝงอยู่แล้วดังนั้นจึงfiมีการจดจำนามแฝงและแบ่งการจัดหา


16
คุณพูดถูก ฉันได้ตั้งค่า: alias fi = 'find -type f | xargs grep -H '
knezi

7
กำจัดมันaliasตอนนี้! :)
Mark Stewart

9
ฉันประหลาดใจที่ทุกคนสามารถจัดการกับปัญหาที่คลุมเครือ ทำได้ดีมากครับ
ทางคณิตศาสตร์

6
@MathematicalOrchid ฉันสงสัยว่ามีอะไรบางอย่างสมนาม (เพราะของเปลือกโต้ตอบ) setถูกตัดออกจากการส่งออกและalias if='foo "'(ลากอ้างเปิดให้ข้อผิดพลาดเกี่ยวกับคำพูดที่ขาดหายไปและเพื่อให้ตัวเลือกสุดท้ายที่ถูก aliasing fi.
Muru
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.