Có thể kiểm tra xem một tập lệnh bash có được thực thi -x
khô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 -x
khô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_X
không được đặt trước đó. Ngoài ra, toàn bộ case
cấ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_X
sang các tập lệnh tiếp theo). Sử dụng case
cấ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 case
và 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 test
chươ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 bash
và 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 -x
và "" (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 xtrace
tương đương với set -x
, lần lượt tương đương với việc đưa ra -x
là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 -o
không có tùy chọn sẽ in trạng thái hiện tại của tất cả các -o
tù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 on
nên là những gì bạn đang tìm kiếm.
*x*
mở rộng ra?