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ó 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:
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!)
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.
*) 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?)
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.
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.
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 [[là 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 bashvà giới thiệu dev này ). Vì vậy, tôi tuyên bố nó là "bash tinh khiết hơn";)
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")
${-//[^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ì ...)
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
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.
*x*mở rộng ra?