Trong câu trả lời cho câu hỏi này về các bình luận trong kịch bản shell , nó được chỉ ra rằng đó :
là một lệnh null hoàn toàn không làm gì cả (nhưng không được sử dụng cho các bình luận).
Điều gì sẽ là tiện ích của một lệnh hoàn toàn không có gì?
Trong câu trả lời cho câu hỏi này về các bình luận trong kịch bản shell , nó được chỉ ra rằng đó :
là một lệnh null hoàn toàn không làm gì cả (nhưng không được sử dụng cho các bình luận).
Điều gì sẽ là tiện ích của một lệnh hoàn toàn không có gì?
Câu trả lời:
Tôi thường sử dụng true
trong các vòng lặp; Tôi nghĩ nó rõ ràng hơn:
while true; do
...
done
Một nơi tôi thấy :
thực sự tiện dụng là trong các báo cáo trường hợp, nếu bạn cần khớp một thứ gì đó nhưng không thực sự muốn làm gì. Ví dụ:
case $answer in
([Yy]*) : ok ;;
(*) echo "stop."; exit 1 ;;
esac
true
cho một điều kiện, :
cho một NOP.
case a in a ) ;; esac
. Có một số vỏ không chấp nhận điều này?
case ${var} in value);; *) do_something;; esac
có thể chấp nhận được. Các :
lệnh là không cần thiết đối với trường hợp có sản phẩm nào.
Ban đầu, nó được sử dụng để xác định rằng đó là chương trình shell Bourne, trái ngược với chương trình biên dịch C. Điều này là trước khi shebang và nhiều ngôn ngữ kịch bản (csh, perl). Bạn vẫn có thể chạy tập lệnh bắt đầu chỉ bằng :
:
$ echo : > /tmp/xyzzy
$ chmod +x /tmp/xyzzy
$ ./xyzzy
Nó thường sẽ chạy tập lệnh chống lại $SHELL
(hoặc /bin/sh
).
Kể từ đó, việc sử dụng chính là để đánh giá các đối số. Tôi vẫn sử dụng:
: ${EDITOR:=vim}
để đặt giá trị mặc định trong tập lệnh.
:
là hữu ích để viết các vòng lặp phải được chấm dứt từ bên trong.
while :
do
...stuff...
done
Điều này sẽ chạy mãi mãi trừ khi break
hoặc exit
được gọi, hoặc shell nhận được tín hiệu kết thúc.
while true; do ...; done
truyền đạt ý định đến người đọc tốt hơnwhile :; do ...; done
Khi bạn muốn một câu lệnh "trừ khi" trong kịch bản shell, bạn có thể sử dụng điều kiện "không", điều này có thể trông ngớ ngẩn đối với một số thử nghiệm hoặc bạn sử dụng ':' trong mệnh đề đúng, với mã thực trong sai- mệnh đề.
if [ some-exotic-condition ]
then
:
else
# Real code here
fi
"Điều kiện kỳ lạ" có thể là điều bạn không muốn phủ nhận hoặc điều đó rõ ràng hơn nhiều nếu bạn không sử dụng "logic tiêu cực".
autoconf
vì việc thêm mặc định :
cho các nhánh trống dễ dàng hơn nhiều so với việc tìm ra cách đảo ngược điều kiện.
!
trước mặt [ some-exotic-condition ]
là ngớ ngẩn, nhưng thừa thãi : else
sau khi nó không ngớ ngẩn.
!
thông báo phủ nhận toàn bộ thành phần ống lệnh. while ! grep ... ; do ... done
hoặc if ! [ ... ] ; then ... fi
. Về cơ bản, nó nằm ngoài test/[]
cú pháp. Xem: pubs.opengroup.org/onlinepub/9699919799/utilities/iêu
Tôi chỉ từng sử dụng điều này ngoài ký tự # để tạm thời nhận ra một dòng, trong tình huống nhận xét dòng tạo ra lỗi cú pháp, do lỗi ngữ pháp shell không cho phép một chuỗi lệnh trống :
if condition ; then
:# temporarily commented out command
fi
Nếu không có: chúng ta có một chuỗi lệnh bị thiếu, đó là lỗi cú pháp.
Có hai trường hợp tôi thấy :
hữu ích:
#!/bin/sh
# set VAR to "default value" if not already set in the environment
: "${VAR=default value}"
# print the value of the VAR variable. Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR}"
Đây là một cách thuận tiện để cho phép người dùng tập lệnh shell của bạn ghi đè cài đặt mà không cần chỉnh sửa tập lệnh. (Tuy nhiên, các đối số dòng lệnh sẽ tốt hơn vì bạn không gặp rủi ro về hành vi không mong muốn nếu người dùng tình cờ có biến bạn sử dụng trong môi trường xuất của họ.) Đây là cách người dùng ghi đè cài đặt:
VAR="other value" ./script
Các ${VAR=value}
cú pháp nói với bộ VAR
để value
nếu VAR
chưa được thiết lập, sau đó mở rộng đến các giá trị của biến. Vì chúng ta không quan tâm đến giá trị của biến, nên nó được truyền dưới dạng đối số cho lệnh no-op :
để loại bỏ nó.
Mặc dù :
là lệnh no-op, việc mở rộng được thực hiện bởi shell (không phải :
lệnh!) Trước khi chạy :
lệnh để việc gán biến vẫn xảy ra (nếu có thể).
Nó cũng có thể được chấp nhận để sử dụng true
hoặc một số lệnh khác thay thế :
, nhưng mã trở nên khó đọc hơn vì ý định không rõ ràng.
Kịch bản sau đây cũng sẽ hoạt động:
#!/bin/sh
# print the value of the VAR variable. Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR=default value}"
Nhưng ở trên là khó khăn hơn nhiều để duy trì. Nếu một dòng sử dụng ${VAR}
được thêm vào phía trên printf
dòng đó , việc mở rộng gán mặc định phải được di chuyển. Nếu nhà phát triển quên di chuyển nhiệm vụ đó, một lỗi sẽ được đưa ra.
Các khối điều kiện trống thường nên tránh, nhưng đôi khi chúng hữu ích:
if some_condition; then
# todo: implement this block of code; for now do nothing.
# the colon below is a no-op to prevent syntax errors
:
fi
Một số người lập luận rằng việc có một if
khối thực sự trống có thể làm cho mã dễ đọc hơn là phủ nhận bài kiểm tra. Ví dụ:
if [ -f foo ] && bar || baz; then
:
else
do_something_here
fi
được cho là dễ đọc hơn:
if ! [ -f foo ] || ! bar && ! baz; then
do_something_here
fi
Tuy nhiên tôi tin rằng có một vài cách tiếp cận khác tốt hơn một khối thực sự trống rỗng:
Đặt điều kiện trong một hàm:
exotic_condition() { [ -f foo ] && bar || baz; }
if ! exotic_condition; then
do_something_here
fi
Đặt điều kiện bên trong dấu ngoặc nhọn (hoặc dấu ngoặc đơn, nhưng dấu ngoặc đơn sinh ra một quy trình con và mọi thay đổi được thực hiện đối với môi trường bên trong lớp con sẽ không hiển thị bên ngoài lớp con) trước khi phủ định:
if ! { [ -f foo ] && bar || baz; } then
do_something_here
fi
Sử dụng ||
thay vì if
:
[ -f foo ] && bar || baz || {
do_something_here
}
Tôi thích cách tiếp cận này khi phản ứng là một lớp lót đơn giản, chẳng hạn như điều kiện khẳng định:
log() { printf '%s\n' "$*"; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$@"; exit 1; }
[ -f foo ] && bar || baz || fatal "condition not met"
Trong lớp vỏ trước bourne cũ trong các phiên bản UNIX cổ, :
lệnh ban đầu được dự định để chỉ định các nhãn cho goto
(đó là một lệnh riêng rẽ vào đầu vào nơi tìm thấy nhãn, vì vậy các nhãn không thể là một cú pháp riêng biệt mà shell know about. if
cũng là một lệnh riêng biệt.) Nó nhanh chóng được sử dụng cho các bình luận, trước khi có một cú pháp bình luận ( #
được sử dụng cho backspace) và ngày nay là xung quanh để tương thích nhiều như mọi thứ.
Ngoài việc sử dụng nó như một câu lệnh không làm gì, bạn có thể sử dụng nó để nhận xét các câu lệnh đơn bằng cách biến chúng thành các đối số cho :.
: echo write this line > myfile
vẫn sẽ tạo một tệp trống.
:
là KHÔNG một cơ chế cho ý kiến đầy đủ.