วิธีทำให้ `local` จับรหัสทางออกได้อย่างไร


11

ในโครงการของฉันฉันมีตัวอย่างต่อไปนี้:

local output="$(bash "${1##*/}")"
echo "$?"

สิ่งนี้จะพิมพ์ค่าศูนย์เนื่องจากการlocalลบlocalจะทำให้$?ตัวแปรทำงานได้อย่างถูกต้อง: ซึ่งจะถือว่ารหัสการออกจาก subshell

คำถามของฉันคือ: ฉันจะเก็บตัวแปรนี้ไว้ในตัวเครื่องได้อย่างไรในขณะที่ยังเก็บค่าการออกได้


1
shellcheckจะไม่เพียงจับปัญหานี้ แต่แนะนำวิธีแก้ปัญหาที่unix.stackexchange.com/a/281749/24718 !
Waleed Khan

คำตอบ:


16
#!/bin/bash
thing() {
   local foo=$(asjkdh) ret="$?"
   echo "$ret"
}

สิ่งนี้จะสะท้อน127รหัสข้อผิดพลาดที่ถูกต้องสำหรับ "ไม่พบคำสั่ง"

คุณสามารถใช้localเพื่อกำหนดมากกว่าหนึ่งตัวแปร ดังนั้นฉันเพียงแค่สร้างตัวแปรท้องถิ่นRETเพื่อจับรหัสทางออกของ subshell ก่อนlocalสำเร็จและตั้งค่า$?เป็นศูนย์


มันรับประกันหรือไม่ว่าการbashประเมินการแสดงออกนี้จากซ้ายไปขวา?
Max Ried

เท่าที่ฉันทราบการกำหนดตัวแปรตามลำดับจากซ้ายไปขวาในบริบทนี้ใช่
DopeGhoti

@ MaxRied ความจริงที่ว่าผลงานนี้น่าเชื่อถือจะปรากฏขึ้นเพื่อระบุว่าใช่มันเป็น อย่างไรก็ตามฉันไม่พบข้อมูลเกี่ยวกับสิ่งนี้ไม่ได้มาจาก POSIX หรือbashคู่มืออ้างอิง
แมว

10
นอกจากนี้การใช้ชื่อตัวแปร all-caps เป็นรูปแบบที่ไม่ดี ดูข้อมูลจำเพาะตัวแปรสภาพแวดล้อม POSIX ที่pubs.opengroup.org/onlinepubs/009695399/basedefs/ …ซึ่งอธิบายชื่อตัวพิมพ์ใหญ่ทั้งหมดเป็นสงวนไว้สำหรับตัวแปรที่มีความหมายกับเชลล์หรือระบบและชื่อที่มีอักขระตัวพิมพ์เล็กอย่างน้อยหนึ่งตัว สงวนไว้สำหรับการใช้งานที่กำหนดโดยแอปพลิเคชันโดยคำนึงว่าตัวแปรเชลล์และตัวแปรสภาพแวดล้อมใช้เนมสเปซร่วมกัน (เนื่องจากในกรณีที่มีการชนกัน
Charles Duffy

ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
terdon

27

ประกาศตัวแปรโลคัลก่อนที่คุณจะกำหนด:

thing() {
  local output
  output="$(bash "${1##*/}")"
  echo "$?"
}

ในความคิดของฉันนี้ยังสามารถอ่านได้มากกว่าการตั้งค่าRETตัวแปรเพิ่มเติม YMMV บนนั้น แต่มันก็ใช้งานได้ตามที่คุณคาดหวัง


2
นี้เป็นมากดีกว่าการใช้ตัวแปรแยกควรจะชัดเจนถ้าคุณต้องการที่จะตรวจสอบรหัสการกลับมาของการมอบหมายงานหลาย: เพียงlocal var1 var2 ...และบ๊อบเป็นลุงของคุณ
l0b0

@ l0b0 Bob เป็นลุงของฉัน : D
cat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.