วิธีคืนค่าการตั้งค่าอย่างถูกต้องเมื่อเรียกใช้สคริปต์โดยใช้“ แหล่งที่มา”


9

ฉันกำลังเขียนสคริปต์ที่ต้องดำเนินการโดยใช้sourceเพราะหน้าที่ของมันคือการแก้ไขสภาพแวดล้อม ในระหว่างสคริปต์ฉันต้องการใช้set -eเพื่อให้ข้อผิดพลาดใด ๆ หยุดสคริปต์ สคริปต์มีลักษณะดังนี้:

#!/bin/bash
set -e
# do something
cd somewhere
source anotherScript

ปัญหาคือว่าset -eยังคงมีผลตามธรรมชาติหลังจากสคริปต์เสร็จสิ้น ฉันจะมั่นใจได้อย่างไรว่าsetตัวเลือกที่เปลี่ยนแปลงนั้นได้รับการคืนค่าอย่างเหมาะสมเมื่อสคริปต์หยุดทำงาน (ไม่ว่าด้วยวิธีใด - โดยการดำเนินการให้สำเร็จหรือเกิดข้อผิดพลาด)



ปัญหาเดียวกัน (สำหรับ-x/ xtraceตัวเลือก) ได้รับการแก้ไขที่การติดตามการเรียกใช้งานการปราบปรามสำหรับคำสั่ง echo หรือไม่
สกอตต์

คำตอบ:


3

วิธีเดียวกันกับที่คุณเปิดใช้งาน: การเรียก buitin set:

$ set -o errexit
$ set -o | grep errexit
errexit         on
$ set +o errexit
$ set -o | grep errexit
errexit         off

จากbash(1)manpage ภายใต้SHELL BUILTIN COMMANDSส่วนคำสั่ง `set ':

-o option-name
The option-name can be one of the following:
    errexit Same as -e.

3
มีวิธีการบันทึก (ทั้งหมด) การตั้งค่าเหล่านี้และกู้คืนในภายหลังหรือไม่
Petr Pudlák

เรียกใช้set -oการตั้งค่าปัจจุบันของคุณที่รู้จัก ให้ชัดเจนเมื่อตั้งค่า / ยกเลิกการตั้งค่าใด ๆ ในสคริปต์ของคุณ
dawud

13

คำสั่งset +oแสดงรายการการตั้งค่าปัจจุบันเป็นคำสั่งที่คืนค่าสถานะเดียวกันเช่น

$ set +o
set +o allexport
set -o braceexpand
set -o emacs
set +o errexit
set +o errtrace
...

คุณสามารถกู้คืนตัวเลือกทั้งหมดในภายหลังได้อย่างง่ายดายหากคุณบันทึกผลลัพธ์นี้ไปยังตัวแปรเชลล์:

SAVED_OPTIONS=$(set +o)
set -e
# do something
eval "$SAVED_OPTIONS"

Bash รวมถึงตัวเลือกที่ไม่ได้มาตรฐาน (ไม่ใช่ POSIX) จำนวนมากที่ถูกปรับโดยใช้shoptคำสั่ง คำสั่งshopt -pสามารถใช้เพื่อบันทึกตัวเลือกเหล่านี้ในลักษณะที่คล้ายกัน

หากคุณต้องการบันทึกและกู้คืนเพียงหนึ่งตัวเลือกคุณสามารถใช้ตัวแปร $ - environment ซึ่งแสดงรายการตัวเลือกปัจจุบันเป็นตัวอักษรเช่น

$ echo $-
himBH

คุณสามารถใช้สิ่งนี้เพื่อบันทึกและกู้คืนตัวเลือกเฉพาะ:

[[ $- = *e* ]]
SAVED_ERREXIT=$?
set -e
# do something
(( $SAVED_ERREXIT )) && set +e

โปรดทราบว่ามันเป็นสิ่งสำคัญมากที่จะไม่พลาดคำพูดที่อยู่รอบ ๆ "$ SAVED_OPTIONS" ในการโทรแบบ eval
Matt

3

ใช้กับดัก RETURN

RETURN กับดักทำงานสำหรับสคริปต์ที่มาเช่นกัน

คำสั่งที่ระบุด้วยกับRETURNดักจะถูกดำเนินการก่อนที่จะดำเนินการต่อหลังจากฟังก์ชั่นเชลล์หรือเชลล์สคริปต์ดำเนินการด้วย.หรือsourceส่งคืน

- https://www.gnu.org/software/bash/manual/bash.html

main_script.sh

#!/usr/bin/env bash
echo "inside main script"
shopt -o errexit
source a_script_to_be_sourced.sh
echo "back inside main script"
shopt -o errexit

a_script_to_be_sourced.sh

trap "$(shopt -p -o errexit)" RETURN
set -e # Equivalents: set -o errexit; shopt -s -o errexit
echo "inside sourced script"
shopt -o errexit

ทดสอบ

$ ./main_script.sh 
inside main script
errexit         off
inside sourced script
errexit         on
back inside main script
errexit         off

2

การเรียกคืนการตั้งค่าที่เปิดใช้งานก่อนหน้านี้สามารถทำได้อย่างรวดเร็วเช่น:

PREV_SETTING=$-  # e.g. himxBH  (there was xtrace)

set +x
# do your script without xtrace, ...

set -$PREV_SETTING

อีกวิธีหนึ่ง (คืนสู่สถานะปิด) AFAIK ไม่มีทางลัดและคำตอบของ Seppo ครอบคลุมทุกกรณี


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