ใน bash scripting อะไรคือความแตกต่างระหว่างการประกาศและตัวแปรปกติ?


43

ในการทุบตีสคริปต์:

เราสร้างตัวแปรโดยการตั้งชื่อ:

abc=ok

หรือเราสามารถใช้ declare

declare abc=ok

ความแตกต่างคืออะไร

และทำไมทุบตีทำหลายวิธีในการสร้างตัวแปร?


6
เมื่อใช้ในฟังก์ชันdeclareให้ NAME เป็นโลคัลเช่นเดียวกับlocalคำสั่ง -gตัวเลือกยับยั้งพฤติกรรมนี้ help declareดู
Cyrus

2
declareทำให้สามารถสร้างอาเรย์เชื่อมโยงจำนวนเต็มและตัวแปรแบบอ่านอย่างเดียว นอกจากนี้มันยังขยายข้อโต้แย้งของมันดังนั้นสิ่งที่declare $name=1เป็นไปได้
choroba

คำตอบ:


34

จากhelp -m declare:

ชื่อ

    declare - ตั้งค่าตัวแปรและคุณสมบัติ

สรุป

    declare[ -aAfFgilnrtux] [ -p] [ name[ ] ...=value

รายละเอียด

    ตั้งค่าตัวแปรและคุณสมบัติ

    ประกาศตัวแปรและให้คุณสมบัติ หากไม่มีการระบุชื่อให้แสดงแอตทริบิวต์และค่าของตัวแปรทั้งหมด

    ตัวเลือก:

      -f
        จำกัด การกระทำหรือแสดงชื่อฟังก์ชันและคำจำกัดความ
      -F
        จำกัด การแสดงผลกับชื่อฟังก์ชันเท่านั้น (รวมถึงหมายเลขบรรทัดและไฟล์ต้นฉบับเมื่อทำการดีบั๊ก)
      -g
        สร้างตัวแปรทั่วโลกเมื่อใช้ในฟังก์ชั่นเปลือก; ถูกเพิกเฉยเป็นอย่างอื่น
      -p
        แสดงคุณสมบัติและค่าของแต่ละ NAME

    ตัวเลือกที่กำหนดคุณลักษณะ:

      -a
        เพื่อจัดทำดัชนีอาร์เรย์ของ NAME (หากรองรับ)
      -A
        การสร้าง NAMEs Array Array (หากสนับสนุน)
      -i
        เพื่อให้ NAME มีแอตทริบิวต์ 'จำนวนเต็ม'
      -l
        เพื่อแปลง NAME ให้เป็นตัวพิมพ์เล็กในการมอบหมาย
      -n
        ทำให้ NAME เป็นการอ้างอิงถึงตัวแปรที่ตั้งชื่อตามค่าของมัน
      -r
        เพื่อสร้าง NAME แบบอ่านอย่างเดียว
      -t
        เพื่อให้ NAME มีแอตทริบิวต์ "ติดตาม"
      -u
        เพื่อแปลง NAME ให้เป็นตัวพิมพ์ใหญ่เมื่อกำหนด
      -x
        เพื่อให้ NAME ส่งออก

    การใช้ ' +' แทน ' -' จะเป็นการปิดแอตทริบิวต์ที่กำหนด

    ตัวแปรที่มีคุณสมบัติจำนวนเต็มมีการประเมินผลทางคณิตศาสตร์ (ดูletคำสั่ง) ดำเนินการเมื่อตัวแปรถูกกำหนดค่า

    เมื่อใช้ในฟังก์ชันdeclareให้ NAME เป็นโลคัลเช่นเดียวกับlocal คำสั่ง ว่า ' -gตัวเลือก' ยับยั้งพฤติกรรมนี้

    สถานะการออก:
    กลับสู่ความสำเร็จเว้นแต่ว่ามีการจัดหาตัวเลือกที่ไม่ถูกต้องหรือข้อผิดพลาดในการกำหนดตัวแปรเกิดขึ้น

ดูสิ่งนี้ด้วย

    ทุบตี (1)

การดำเนินงาน

    GNU ทุบตี, รุ่น 4.3.11 (1) - ปล่อย (i686-pc-linux-gnu)
    ลิขสิทธิ์ (C) 2013 มูลนิธิซอฟต์แวร์เสรี, Inc.
    ใบอนุญาต GPLv3 +: GNU GPL รุ่น 3 หรือใหม่กว่า <http://gnu.org/ ใบอนุญาต / gpl.html>


ดังนั้นdeclareจะใช้สำหรับการตั้งค่าตัวแปรและคุณลักษณะ

ให้ฉันแสดงการใช้สองคุณลักษณะด้วยตัวอย่างง่ายๆ:

$ # First Example:
$ declare -r abc=ok
$ echo $abc
ok
$ abc=not-ok
bash: abc: readonly variable


$ # Second Example:
$ declare -i x=10
$ echo $x
10
$ x=ok
$ echo $x
0
$ x=15
$ echo $x
15
$ x=15+5
$ echo $x
20

จากตัวอย่างข้างต้นฉันคิดว่าคุณควรเข้าใจการใช้งานของdeclareตัวแปรมากกว่าตัวแปรปกติ! declareation ชนิดนี้มีประโยชน์ในฟังก์ชั่นมีการวนรอบด้วยสคริปต์

เยี่ยมชมตัวแปรพิมพ์ดีด: ประกาศหรือเรียงพิมพ์


ใช่ "และคุณสมบัติ" เป็นจุด! นี่คือความแตกต่าง
lovespring

ที่ดี! ฉันรักตัวอย่างวิธีที่ดีที่สุดในการสอน / เรียนรู้ ขอบคุณ!
turkenh

1
คุณต้องรู้ว่า "คุณสมบัติ" คืออะไรเพื่อให้เข้าใจคำตอบนี้ เป็นคุณสมบัติของตัวแปรเช่น 'จำนวนเต็ม', 'อาร์เรย์' หรือ 'อ่านได้อย่างเดียว'
Noumenon

11

abc=okabcกำหนดค่าให้กับตัวแปร ประกาศตัวแปรที่เรียกว่าdeclare abc ทั้งสองสามารถนำมารวมเป็นabcdeclare abc=ok

ใน bash เช่นเชลล์อื่น ๆ ไม่จำเป็นต้องประกาศตัวแปรสตริงและอาร์เรย์ดังนั้นจึงdeclareไม่จำเป็นเว้นแต่คุณจะต้องการส่งตัวเลือกเช่นdeclare -A abcสร้างabcอาเรย์แบบเชื่อมโยงหรือdeclare -rสร้างตัวแปรแบบอ่านอย่างเดียว อย่างไรก็ตามภายในฟังก์ชั่นdeclareจะสร้างความแตกต่าง: มันทำให้ตัวแปรเป็นท้องถิ่นของฟังก์ชั่นซึ่งหมายความว่าค่าของตัวแปรนอกฟังก์ชั่น (ถ้ามี) จะถูกเก็บไว้ (ยกเว้นว่าคุณใช้declare -gซึ่งทำให้ตัวแปรไม่ใช่แบบโลคอลสิ่งนี้มีประโยชน์เมื่อรวมกับตัวเลือกอื่น ๆ เช่นdeclare -gAเพื่อสร้างอาเรย์ส่วนกลางแบบเชื่อมโยงในฟังก์ชัน) ตัวอย่าง:

f () {
  declare a
  a='a in f'
  b='b in f'
  echo "From f: a is $a"
  echo "From f: b is $b"
}
a='Initial a'
b='Initial b'
f
echo "After f: a is $a"
echo "After f: b is $b"

เอาท์พุท:

From f: a is a in f
From f: b is b in f
After f: a is Initial a
After f: b is b in f

อีกสิ่งที่คุณสามารถทำได้กับdeclarebuiltin ก็คือ

declarebuiltin เป็นเอกลักษณ์ทุบตี มันเป็นแรงบันดาลใจอย่างมากและใกล้เคียงกับtypesetbuiltin ของ ksh และ bash typesetเป็นคำพ้องความหมายdeclareสำหรับความเข้ากันได้ (ฉันไม่รู้ว่าทำไมทุบตีไม่เพียงแค่เรียกมันtypeset) มีคำพ้องความหมายที่สาม, local. นอกจากนี้ยังมีexportซึ่งเป็นเหมือนกันdeclare -xอีกครั้งสำหรับความเข้ากันได้ (กับเชลล์สไตล์ Bourne ทุกตัว)


ใช่! 'และตัวเลือก' คือประเด็น ป.ล. ถ้าฉันออกแบบทุบตีฉันจะปล่อยให้พฤติกรรมของ "ประกาศ" ทำอะไรบางอย่างที่แตกต่างกัน ทำให้สิ่งนี้ง่าย
59

คำตอบที่ดี คำถามต่อไปซึ่งเป็นหนึ่งในexportนั้นlocalและdeclareเข้ากันได้มากที่สุดกับหอยอื่น ๆ ?
0xc0de

1
@ 0xc0de มีอยู่ในทุกสายพันธุ์ของexport มีอยู่ใน bash และ zsh เท่านั้นใน bash มีอยู่ใน ksh, bash และ zsh shlocaldeclaretypeset
Gilles 'หยุดความชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.