หลีกเลี่ยงการเรียกใช้สคริปต์หากไม่ได้กำหนดตัวแปร


18

ฉันมีสคริปต์ดูเหมือนว่า:

c=0
for f in */*; do
cp -v "$f" "/myhome/CE$(printf '%0*d' 2 $BATCHNUM)-new-stuctures_extracted/test-$(printf '%0*d' 5 $c)"
c=$((c=c+1))
done

อย่างไรก็ตามผู้ใช้ต้องจัดให้มีการเรียกตัวแปร BATCHNUM และฉันต้องบังคับให้สคริปต์นี้หยุดทำงาน จะดีกว่าถ้าฉันบังคับให้สคริปต์ที่เรียกสคริปต์นี้หยุดทำงานด้วย (หรือแม้แต่ # 1 สคริปต์ที่เรียกใช้สคริปต์ # 2 ซึ่งเรียกสคริปต์นี้)

คำตอบ:


30

วิธีที่เร็วที่สุดน่าจะเพิ่มสองบรรทัดนี้ไปที่จุดเริ่มต้นของสคริปต์:

set -u # or set -o nounset
: "$BATCHNUM"

บรรทัดแรกตั้งค่าnounsetตัวเลือกในเชลล์ที่รันสคริปต์ซึ่งจะยกเลิกหากคุณพยายามขยายตัวแปรที่ยังไม่ได้ตั้งค่า ที่สองขยาย$BATCHNUMในบริบทของ no-op เพื่อทริกเกอร์การยกเลิกก่อนที่จะทำสิ่งอื่น

หากคุณต้องการข้อความแสดงข้อผิดพลาดที่เป็นประโยชน์คุณสามารถเขียนแทน:

if [[ -z "$BATCHNUM" ]]; then
    echo "Must provide BATCHNUM in environment" 1>&2
    exit 1
fi

หรือคล้ายกัน


18

ที่นี่คุณต้องการตรวจสอบการBATCHNUMตั้งค่าและไม่เป็นโมฆะ

POSIX เชลล์จัดเตรียมการขยายพารามิเตอร์สำหรับงานนี้ เพียงเพิ่มบรรทัดนี้ก่อนใช้BATCHNUM:

: "${BATCHNUM:?Variable not set or empty}"

หรือดีกว่าเพื่อตั้งค่าเริ่มต้นBATCHNUMหากผู้ใช้ไม่ได้ระบุ:

: "${BATCHNUM:=3}"

4
[ -n "$BATCHNUM" ] || { kill "$PPID"; exit 1; }
#Unless $BATCHNUM is defined and unempty, ask parent process to exit and exit w/ 1

สิ่งนี้จะใช้ได้กับ bash และใน POSIX sh ฉันไม่ต้องการแยกความแตกต่างระหว่างตัวแปรว่างเปล่าและตัวแปรที่ไม่ได้กำหนด (เช่นฉันไม่ชอบset -uแต่นั่นเป็นเพียงฉัน)


2

เส้น

if [ -z "$BATCHNUM" ]; then
    exit 2;
fi

$BATCHNUMตรวจสอบที่ว่างเปล่า ด้วย$PPIDคุณสามารถทำสิ่งที่เป็นอันตรายที่คุณต้องการให้พ่อแม่ของคุณ ( kill $PPID) ฆ่าปู่ย่าตายายของคุณคุณจำเป็นต้องได้รับกระบวนการ id โดยวิธีการอื่น ๆ /proc/$PPIDเช่นการดูข้อมูลใน

อย่างไรก็ตามหากพ่อแม่ของคุณเสียชีวิตก็จะส่งสัญญาณ ( SIGHUP) ถึงคุณดังนั้นคุณต้องดักจับมันก่อนที่จะเริ่มฆ่าใคร:

trap '' SIGHUP

Update:ถ้าคุณคิดว่าคุณจะต้องฆ่าพ่อแม่ของคุณคุณทำผิด เพียงส่งคืน exitcode ที่มีความหมายแบบเต็ม ผู้ปกครองควรตรวจสอบรหัสส่งคืนของสคริปต์ที่เรียกว่าและตอบสนองตาม


1
โหดเล็กน้อย .... :)
40780

1

ในการทดสอบว่าBATCHNUMมีการกำหนดหรือไม่และหากไม่ได้ดำเนินการ:

if [ -n "${BATCHNUM-a}" ]; then
  echo >&2 "Fatal error: BATCHNUM not set"
  exit 2
fi

หากคุณยังต้องการที่จะปฏิเสธกรณีที่BATCHNUMเป็นที่ว่างเปล่าให้ใช้แทน${BATCHNUM:+a} ${BATCHNUM+a}สำหรับข้อมูลเกี่ยวกับ${VARIABLE+TEXT_IF_NULL}การสร้างการขยายตัวพารามิเตอร์ให้ดูเช่นคู่มือการทุบตี

อย่าฆ่ากระบวนการผู้ปกครอง คุณไม่รู้ว่ากระบวนการหลักคืออะไร หากสคริปต์บางตัวที่เรียกใช้สคริปต์นี้จำเป็นต้องยกเลิกหากสคริปต์นี้ยกเลิกให้ตรวจสอบสถานะการออกของสคริปต์นี้ เช่นในสคริปต์ # 2:

script3 || exit $?

หรือใช้set -eเพื่อยกเลิกสคริปต์หากคำสั่งใด ๆ ส่งคืนสถานะความล้มเหลว (ไม่ใช่ศูนย์)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.