Làm cách nào để khôi phục chính xác các cài đặt khi chạy tập lệnh bằng cách sử dụng mã nguồn Cameron?


9

Tôi đang viết một kịch bản cần được thực thi bằng cách sử dụng source, vì nhiệm vụ của nó là sửa đổi môi trường. Trong tập lệnh, tôi muốn sử dụng set -eđể bất kỳ lỗi nào dừng tập lệnh. Kịch bản trông như thế này:

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

Vấn đề là set -etự nhiên vẫn có hiệu lực sau khi kịch bản kết thúc. Làm cách nào tôi có thể đảm bảo rằng settùy chọn đã thay đổi được khôi phục đúng giá trị phổ biến của nó khi tập lệnh dừng (theo bất kỳ cách nào - bằng cách hoàn thành thành công hoặc xảy ra lỗi)?



Vấn đề tương tự (đối với tùy chọn -x/ xtrace) được giải quyết tại dấu vết thực thi Suppress cho lệnh echo?
Scott

Câu trả lời:


3

Chính xác giống như cách bạn kích hoạt nó: gọi buitin set:

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

Từ bash(1)trang, bên dưới SHELL BUILTIN COMMANDSphần, lệnh 'set':

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

3
Có cách nào để lưu (tất cả) các cài đặt này và khôi phục chúng sau này không?
Petr Pudlák

Chạy set -ođể biết thiết lập hiện tại của bạn. Hãy rõ ràng khi cài đặt / bỏ đặt bất kỳ trong số chúng trên tập lệnh của bạn.
dawud

12

Lệnh set +oliệt kê các cài đặt hiện tại dưới dạng các lệnh khôi phục trạng thái tương tự, ví dụ:

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

Bạn có thể dễ dàng khôi phục tất cả các tùy chọn sau, nếu bạn lưu kết quả đầu ra này vào biến shell:

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

Bash cũng bao gồm một số tùy chọn không chuẩn (không phải POSIX) được điều chỉnh bằng shoptlệnh. Lệnh shopt -pcó thể được sử dụng để lưu các tùy chọn này theo cách tương tự.

Nếu bạn chỉ muốn lưu và khôi phục một tùy chọn, bạn có thể sử dụng biến $ - môi trường, liệt kê bộ tùy chọn hiện tại dưới dạng chữ cái, ví dụ:

$ echo $-
himBH

Bạn có thể sử dụng một cái gì đó như thế này để lưu và khôi phục một tùy chọn cụ thể:

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

Lưu ý rằng điều rất quan trọng là không bỏ lỡ các trích dẫn xung quanh "$ SAVED_OPTIONS" trong cuộc gọi tệ nạn.
Matt

3

Sử dụng bẫy TRẢ LẠI

RETURN bẫy cũng hoạt động cho các tập lệnh có nguồn gốc, quá.

Các lệnh được chỉ định với một RETURNbẫy được thực thi trước khi thực hiện lại sau khi hàm shell hoặc tập lệnh shell được thực thi với .hoặc sourcetrả về.

- 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

Kiểm tra

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

2

Khôi phục cài đặt kích hoạt trước đó có thể được thực hiện nhanh chóng như sau:

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

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

set -$PREV_SETTING

Một cách khác (khôi phục lại trạng thái tắt) AFAIK không có lối tắt như vậy và câu trả lời của Seppo bao gồm tất cả các trường hợp.


Mã của bạn dưới dạng văn bản mang lại -bash: set: -i: invalid option-icờ lưu ý một vỏ tương tác.
19 lúc 21 giờ 50 phút
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.