Bash: kiểm tra xem tập lệnh gốc có được chạy với `-x` không


7

Có thể kiểm tra xem một tập lệnh bash có được thực thi -xkhông?

Tôi đang viết một tập lệnh cũng chạy một số tập lệnh từ xa và tôi muốn có thể làm một cái gì đó như:

USE_X="$( run_with_x && "-x" || "" )"
ssh $host "bash $USE_X some_script.sh"

Câu trả lời:


9

Chỉ cần nhìn vào $-biến.

USE_X=`case "$-" in *x*) echo "-x" ;; esac`

(Yup, tôi đã xoay sở để làm điều đó mà không cần gọi grep. Lưu các pids!)


những gì không *x*mở rộng ra?
bbaja42

2
Thật là một sự lãng phí của pid! case $- in *x*) USE_X="-x";; *) USE_X=;; esac@ bbaja42 Nó không mở rộng ra bất cứ điều gì: đó là một mẫu mà chuỗi $-được khớp với.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Ví dụ của bạn cũng chứa phần không cần thiết: *) USE_X=;;không thay đổi gì, nếu USE_Xkhông được đặt trước đó. Ngoài ra, toàn bộ casecấu trúc là không cần thiết ( xem phiên bản của tôi - không đơn giản hơn sao?)
rozcietrzewiacz

@rozcietrzewiacz Phần này là không cần thiết nếu USE_Xđã được khởi tạo trước đó. Tôi không xem xét phiên bản của bạn đơn giản hơn: nó ngắn hơn một vài ký tự (và thậm chí chỉ khi USE_Xđã được khởi tạo, nếu không nó dài hơn), nhưng phải trả giá bằng sự rõ ràng và tính di động.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Tính di động không phải là chủ đề của câu hỏi này, nó là về bash. Việc khởi tạo USE_X là không cần thiết cho mục đích sử dụng của OP (để chuyển $USE_Xsang các tập lệnh tiếp theo). Sử dụng casecấu trúc trông ít rõ ràng và tự nhiên hơn so với đánh giá điều kiện thông thường theo quan điểm của tôi.
rozcietrzewiacz

6

Có lẽ là cách phân tích cú pháp đơn giản nhất $-, tương tự như phương thức của dagbrown (cũng thuần túy bash), nhưng không sử dụng casevà backticks (subshell):

if  [[ ${-/x} != $- ]] ; then USE_X="-x"; fi

hoặc thậm chí ngắn hơn:

[[ ${-/x} != $- ]] && USE_X="-x"

Lưu ý rằng [[không một lời gọi testchương trình dựng sẵn (như là trường hợp với [), nhưng một cấu trúc cú pháp bash (theo man bashgiới thiệu dev này ). Vì vậy, tôi tuyên bố nó là "bash tinh khiết hơn";)


Giải pháp tốt đẹp. Tôi đề nghị gắn thẻ '|| USE_X = "+ x" 'ở cuối biểu thức thứ hai để sau đó bạn có thể gọi' set "$ USE_X" 'và nó sẽ hoạt động để khôi phục cài đặt ban đầu cho dù xtrace có được đặt hay không.
Phile nhị phân

6

Biểu thức này sẽ đúng nếu tập lệnh được chạy với -x, sai nếu không: [[ $- =~ x ]] Vì vậy, biểu thức này sẽ là "-x" nếu tập lệnh được chạy với -xvà "" (trống) nếu không:$([[ $- =~ x ]] && echo "-x")


Thật khó để nói "có thể đọc" và "bash" trong cùng một câu, nhưng vì bất kỳ người dùng bash không bình thường nào PHẢI làm quen với cú pháp bash regex, câu trả lời (được bình chọn thấp nhất) của bạn sẽ thắng trong khả năng đọc trong sách của tôi (và , tất nhiên, không yêu cầu bắt đầu bất kỳ quy trình hoặc bất cứ điều gì không hiệu quả đáng kinh ngạc).
Ron Burk

Đây là câu trả lời tốt nhất!
Chris Cogdon

Biểu thức này sẽ xóa tất cả các ký tự không phải x khỏi $ -, vì vậy nó trống nếu không có x: ${-//[^x]}Nếu bạn gán giá trị này cho biến, như: x=${-//[^x]}thì biểu thức sau sẽ trống khi không có x và -x nếu không: ${x:+-x} Kết hợp như : x=${-//[^x]} USE_X=${x:+-x} Hoặc nếu bạn không muốn sử dụng một biến phụ, bạn có thể sử dụng lại USE_X: USE_X=${-//[^x]} USE_X=${USE_X:+-x} Điều này nhanh hơn nhiều so với thực hiện so sánh biểu thức thông thường! (Nhưng ít đọc hơn khi chỉ nhìn vào mã, tìm hiểu xem nó làm gì ...)
PePa

4

Sau khi đọc trang con người và grepping cho mọi thứ, đây là giải pháp:

$ cat show_x.sh
#!/bin/bash
if [ "$(set | grep xtrace)" ]; then
    echo "xtrace is on. :D"
else
    echo "xtrace is off. :("
fi

Kết quả:

$ bash show_x.sh 
xtrace is off. :(

$ bash -x show_x.sh 
++ set
++ grep xtrace
+ '[' SHELLOPTS=braceexpand:hashall:interactive-comments:xtrace ']'
+ echo 'xtrace is on. :D'
xtrace is on. :D

"set" sẽ hiển thị cho bạn tất cả các hàm và env vars, và nếu bất kỳ hàm nào chứa "xtrace" thì giải pháp sẽ thất bại.
Chris Cogdon

3

Các tài liệu trang bash man set -o xtracetương đương với set -x, lần lượt tương đương với việc đưa ra -xlàm đối số cho trình bao. (Cho đến nay, điều này tương thích với SUSv3 sh, với cảnh báo -o optionđược yêu cầu "nếu hệ thống hỗ trợ tùy chọn Tiện ích di động người dùng".)

Ngoài ra, set -okhông có tùy chọn sẽ in trạng thái hiện tại của tất cả các -otùy chọn. (SUSv3 cũng chỉ rõ điều này, nhưng không hữu ích; định dạng không được chỉ định, do đó bạn chỉ có thể phụ thuộc vào nó nếu bạn biết bạn đang chạy shell sử dụng định dạng tương tự như bash.)

Vì vậy, đường ống set -o | grep xtrace | grep -q onnên là những gì bạn đang tìm kiếm.

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.