#!/bin/bash
function0()
{
local t1=$(exit 1)
echo $t1
}
function0
echo
in giá trị trống. Tôi mong đợi:
1
Tại sao t1
biến không được gán giá trị trả về của lệnh thoát - 1
?
#!/bin/bash
function0()
{
local t1=$(exit 1)
echo $t1
}
function0
echo
in giá trị trống. Tôi mong đợi:
1
Tại sao t1
biến không được gán giá trị trả về của lệnh thoát - 1
?
Câu trả lời:
local t1=$(exit 1)
nói với cái vỏ để:
exit 1
trong một subshell;t1
, cục bộ cho hàm.Do đó, bình thường mà t1
kết thúc là trống rỗng.
( $()
được gọi là thay thế lệnh .)
Mã thoát luôn được gán cho $?
, vì vậy bạn có thể làm
function0()
{
(exit 1)
echo "$?"
}
để có được hiệu quả mà bạn đang tìm kiếm. Tất nhiên bạn có thể gán $?
cho một biến khác:
function0()
{
(exit 1)
local t1=$?
echo "$t1"
}
$(trap 'printf "::ERRNO:$?"' 0; # now do whatever however
Mã thoát được lưu trữ trong $? Biến đổi. Sử dụng thay thế lệnh chỉ thu được đầu ra, bạn nên sử dụng (...) để tạo lớp con :
#!/bin/bash
func() {
(exit 1)
local t1=$?
printf '%d\n' "$t1"
}
func
t1=$?
là sử dụng nó, không? và sẽ không $?
bị tắc nghẽn bởi nhiệm vụ op? Tôi đoán tôi đang hỏi liệu có nên khôngprintf '%d\n' "${t1}"
Trong bash
tác phẩm này:
loc(){ local "x=$(exit "$1"):$?"
printf '$%s:\t%d\n' \
x "${x##*:}" \? "$?"
}
Nó phải làm theo thứ tự đánh giá lệnh và gán biến. local
có giá trị trả về của riêng nó - và đó là lệnh hiện đang thực thi, không phải là lệnh thay thế. Lý do như ...
x=$(exit 1); echo "$?"
... có thể trả về 1 là vì không bao giờ có lệnh trả về ngoại trừ lệnh chạy con để gán $x
giá trị - vì vậy $?
thực tế không bị ghi đè như trong thực tế mọi trường hợp khác sử dụng thay thế lệnh.
Dù sao, với local
nó cũng bị tắc nghẽn - nhưng nếu bạn bắt được nó vào đúng thời điểm - đó là trong khi các bản mở rộng vẫn đang được đánh giá và trước khi local
các thói quen có thể bị chặn lại - bạn vẫn có thể gán nó.
unset x; loc 130; echo "${x-\$x is unset}"
... bản in ...
$x: 130
$?: 0
$x is unset
Mặc dù vậy, bạn nên biết rằng trong nhiều hệ vỏ, bạn không thể dựa vào $?
việc đánh giá giữa theo cách đó. Trên thực tế, đó có lẽ là do những cái vỏ đó không bận tâm đến việc đánh giá lại ở mọi thời điểm có thể xảy ra như có lẽ bash
- điều mà tôi cho rằng có lẽ là hành vi tốt hơn so với bash
. Bạn có thực sự muốn trình thông dịch của bạn đánh giá đệ quy các giá trị vòng lặp rất có khả năng bị ghi đè trước khi bạn có cơ hội sử dụng chúng không?
Dù sao, đó là cách bạn có thể làm điều đó.
Tùy thuộc vào lý do tại sao bạn đang cố lấy mã thoát, bạn cũng có thể chạy if some-command; then echo "Success $?"; else echo "Failure $?"; fi
mà không làm gì với đầu ra của lệnh, nó chỉ đánh giá mã thoát của lệnh chạy. Bạn có thể thêm or
( or
$ ( around the command and you'll still get the same results. A better example might be
nếu grep -q 'somestring' somefile; sau đó lặp lại "Đã tìm thấy mã thoát nội địa là $?"; Khác "Không tìm thấy mã thoát nội địa là $?"; Fi`.
Bạn cũng có thể kiểm tra mã trả về của hàm có thể là return 3
mã trả về rõ ràng hoặc mã ngụ ý là kết quả của lệnh cuối cùng, trong trường hợp này bạn cần cẩn thận rằng bạn không có mã echo
ở cuối chức năng, nếu không nó che / đặt lại mã thoát trước đó.
command_last () {
echo "True is `true`"
echo "False is `false`"
false
}
command_last; echo $?
# Outputs:
# True is 0
# False is 1
# 1
echo_last () {
echo "True is `true`"
echo "False is `false`"
false
# echo'ing literally anything (or nothing) returns true aka exit 0
echo
}
echo_last; echo $?
# Outputs:
# True is 0
# False is 1
# # Blank line due to empty echo
# 0
Cuối cùng là một mánh khóe bẩn vì bạn không thể làm được VAR=(SOME_COMMAND)
vì đó VAR=()
là một định nghĩa mảng nên bạn cần phải làm VAR=( $(echo 'Some value') )
.