#!/bin/bash
function0()
{
local t1=$(exit 1)
echo $t1
}
function0
echo
พิมพ์ค่าว่าง ฉันคาดหวัง:
1
ทำไมไม่t1
ได้รับมอบหมายตัวแปรค่าตอบแทนคำสั่งทางออกของ - 1
?
#!/bin/bash
function0()
{
local t1=$(exit 1)
echo $t1
}
function0
echo
พิมพ์ค่าว่าง ฉันคาดหวัง:
1
ทำไมไม่t1
ได้รับมอบหมายตัวแปรค่าตอบแทนคำสั่งทางออกของ - 1
?
คำตอบ:
local t1=$(exit 1)
บอกเชลล์ให้กับ:
exit 1
ใน subshell;t1
ท้องถิ่นเพื่อฟังก์ชั่นมันเป็นเรื่องปกติที่t1
กลายเป็นว่าว่างเปล่า
( $()
เรียกว่าการทดแทนคำสั่ง )
รหัสทางออกจะถูกกำหนดไว้เสมอเพื่อ$?
ให้คุณสามารถทำได้
function0()
{
(exit 1)
echo "$?"
}
เพื่อให้ได้เอฟเฟกต์ที่คุณต้องการ แน่นอนคุณสามารถกำหนด$?
ให้กับตัวแปรอื่น:
function0()
{
(exit 1)
local t1=$?
echo "$t1"
}
$(trap 'printf "::ERRNO:$?"' 0; # now do whatever however
รหัสออกถูกเก็บเป็น$? ตัวแปร. การใช้การแทนที่คำสั่งจะจับเฉพาะเอาต์พุตคุณควรใช้(... ) เพื่อสร้างเชลล์ย่อย :
#!/bin/bash
func() {
(exit 1)
local t1=$?
printf '%d\n' "$t1"
}
func
t1=$?
คือการใช้มันไม่ใช่? และจะไม่$?
ได้รับการอุดตันโดย op ที่ได้รับมอบหมาย? ฉันเดาว่าฉันถามว่ามันไม่ควรจะเป็นprintf '%d\n' "${t1}"
ในbash
งานนี้:
loc(){ local "x=$(exit "$1"):$?"
printf '$%s:\t%d\n' \
x "${x##*:}" \? "$?"
}
มันเกี่ยวข้องกับลำดับของการประเมินคำสั่งและการกำหนดตัวแปร local
มีค่าส่งคืนทั้งหมดเป็นของตัวเอง - และเป็นคำสั่งในการดำเนินการในปัจจุบันไม่ใช่การทดแทนคำสั่ง เหตุผลที่ชอบ ...
x=$(exit 1); echo "$?"
... สามารถคืนค่า 1 ได้เนื่องจากไม่มีการส่งคืนในคำสั่งนั้นยกเว้นการเรียกใช้ subshell เพื่อกำหนด$x
ค่าของ - ดังนั้นจึง$?
ไม่ได้รับการอุดตันเหมือนในกรณีจริง ๆ ทุกกรณีที่ใช้การแทนที่คำสั่ง
อย่างไรก็ตามกับlocal
มันไม่ได้รับ clobbered - แต่ถ้าคุณจับมันที่เพียงเวลาที่เหมาะสม - ซึ่งเป็นขณะที่การขยายตัวยังคงถูกประเมินและก่อนที่จะ local
's กิจวัตรมีโอกาสที่จะบังคับมัน - คุณยังสามารถกำหนด
unset x; loc 130; echo "${x-\$x is unset}"
พิมพ์ ... ...
$x: 130
$?: 0
$x is unset
คุณควรรู้ว่าในหลาย ๆ เชลล์คุณไม่สามารถพึ่งพา$?
การตั้งค่าการประเมินกลางด้วยวิธีนี้ ในความเป็นจริงที่ว่าอาจจะเป็นเพราะเปลือกหอยเหล่านั้นไม่ได้รบกวนการประเมินอีกครั้งในทุกจุดเชื่อมต่อที่เป็นไปได้อาจจะbash
ไม่ - ซึ่งผมจะเถียงเป็นพฤติกรรมที่อาจจะดีกว่าbash
's คุณต้องการให้ล่ามวนวนซ้ำวนซ้ำซึ่งมีแนวโน้มที่จะถูกเขียนทับก่อนที่คุณจะมีโอกาสได้ใช้จริงหรือไม่?
อย่างไรก็ตามนั่นคือวิธีที่คุณสามารถทำได้
ขึ้นอยู่กับสาเหตุที่คุณพยายามรับรหัสทางออกที่คุณสามารถเรียกใช้if some-command; then echo "Success $?"; else echo "Failure $?"; fi
ซึ่งไม่ได้ทำอะไรกับผลลัพธ์ของคำสั่ง แต่จะประเมินรหัสทางออกของการเรียกใช้คำสั่ง คุณสามารถเพิ่มor
( or
$ ( around the command and you'll still get the same results. A better example might be
ถ้า grep -q 'somestring' somefile; echo "พบรหัสทางออก somestring เป็น $?"; อื่น "ไม่พบรหัสทางออก somestring เป็น $?"; fi`
คุณสามารถทดสอบโค้ดส่งคืนของฟังก์ชันซึ่งอาจเป็นreturn 3
โค้ดส่งคืนอย่างชัดเจนหรือโดยนัยซึ่งเป็นผลมาจากคำสั่งสุดท้ายในกรณีนี้คุณต้องระวังว่าคุณไม่มีแอนecho
ที่ส่วนท้ายของ ฟังก์ชั่นมิฉะนั้นจะมาสก์ / รีเซ็ตรหัสทางออกก่อนหน้า
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
ในที่สุดก็เป็นเคล็ดลับที่สกปรกเนื่องจากคุณไม่สามารถทำVAR=(SOME_COMMAND)
เพราะเป็นคำนิยามอาร์เรย์ดังนั้นคุณจำเป็นต้องVAR=()
VAR=( $(echo 'Some value') )