Bash: ตรวจจับ execute กับ source ในสคริปต์หรือไม่?


19

ฉันมีสคริปต์ที่ทิ้งกระจุยกระจายรอบระบบแฟ้มของฉัน (ผลข้างเคียงของกระบวนการสร้าง) ที่กำหนดตัวแปรสภาพแวดล้อมทั่วโลกบางอย่าง (LD_LIBRARY_PATH, PATH, ROOTDIR และอื่น ๆ ) ที่ต้องอยู่ในเปลือกของฉันสำหรับการดำเนินการที่เหมาะสม แน่นอนนั่นหมายความว่าฉันต้องการsource script.shหรือ. script.shทำให้มันใช้งานได้และไม่ใช่./script.sh(ซึ่งจะวางไข่เชลล์ใหม่และไม่ตั้งค่าตัวแปรในเชลล์ปัจจุบันของฉัน)

มีสิ่งใดบ้างที่ฉันสามารถเพิ่มลงในสคริปต์เพื่อป้องกัน (หรือเตือน) คนที่ทำงานอยู่./script.shหรือไม่

คำตอบ:


15

ในเชลล์สคริปต์$0คือชื่อของสคริปต์ที่รันอยู่ในปัจจุบัน คุณสามารถใช้สิ่งนี้เพื่อบอกว่าคุณมีที่มาหรือใช้งานเช่นนี้:

if [[ "$(basename -- "$0")" == "script.sh" ]]; then
    echo "Don't run $0, source it" >&2
    exit 1
fi

5

วิธีที่ง่ายที่สุดbashคือ:

if [ "$0" = "$BASH_SOURCE" ]; then
    echo "Error: Script must be sourced"
    exit 1
fi

$BASH_SOURCE มีชื่อ / พา ธ ของสคริปต์เสมอ

$0 มีเพียงชื่อ / พา ธ ของสคริปต์เมื่อไม่ได้รับที่มา

ดังนั้นเมื่อพวกเขาตรงกันนั่นหมายความว่าสคริปต์ไม่ได้มีที่มา


1

นี้ได้รับการกล่าวถึงในดังนั้น คำตอบมากที่สุด upvoted โดย @barroyoพูดกับการใช้งาน

[[ "${BASH_SOURCE[0]}" != "${0}" ]] && echo "script ${BASH_SOURCE[0]} is being sourced ..."

@ จะ: คู่มือพูดว่า: ตัวแปรอาเรย์ที่สมาชิกเป็นชื่อไฟล์ต้นฉบับซึ่งชื่อฟังก์ชันเชลล์ที่สอดคล้องกันในตัวแปรอาร์เรย์ FUNCNAME ถูกกำหนดไว้ ฟังก์ชั่นอย่างไร?
serv-inc

1

ตัวเลือกอื่นอาจเป็นการลบสิทธิการใช้งาน ในกรณีนั้นไม่สามารถดำเนินการได้ แต่ยังสามารถจัดหาได้


1
สิ่งนี้ไม่สมบูรณ์ คุณยังคงสามารถเรียกใช้สคริปต์bash scriptโดยไม่คำนึงถึงแฟล็กรันบนสคริปต์ นอกจากนี้ภายใต้ Cygwin (นับจำนวนนี้หรือไม่) คุณไม่สามารถลบธงที่ดำเนินการได้
Tino

0

นอกจากนี้เพื่อตรวจสอบ $ 0 ( คำตอบมิเคล ) อาจมีประโยชน์ในการเปลี่ยนนามสกุลจาก. sh เป็น. src เป็นต้น มันจะช่วยให้เข้าใจใครก็ตามที่ไม่ควรเรียกใช้สคริปต์นี้


0

สร้างล่ามที่กำหนดเองsource_reminder:

#!/bin/sh
printf "%s\n" "Source me!" >&2
exit 1

อย่าลืมทำให้มันใช้งานได้ จากนั้นใช้ในสคริปต์ของคุณ:

#!/path/to/your/source_reminder
foo
bar
whatever

ตอนนี้ถ้าคุณเรียกใช้สคริปต์โดยไม่ต้องจัดหาการแจ้งเตือนจะทำงานของมัน


รับได้สวย. #!/bin/echo do not executeหรือหรือ#!/bin/false #!/usr/bin/awk BEGIN { print "you must source " ARGV[1]; exit(1) }อย่างไรก็ตามนี่ไม่ได้เกิดกรณีที่สคริปต์ถูกดำเนินการด้วยบางสิ่งที่คล้ายกันsh script(เนื่องจากไม่สนใจ Shebang)
Tino
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.