Trong bash scripting, có gì khác nhau giữa khai báo và một biến bình thường?


43

Trong kịch bản bash:

chúng ta tạo biến bằng cách chỉ đặt tên cho nó:

abc=ok

hoặc chúng ta có thể sử dụng declare

declare abc=ok

có gì khác biệt?

và tại sao bash tạo ra nhiều cách để tạo một biến?


6
Khi được sử dụng trong một hàm, đặt declareTÊN cục bộ, như với locallệnh. Các -gtùy chọn ngăn chặn hành vi này. Xem help declare.
Cyrus

2
declarelàm cho nó có thể tạo các mảng kết hợp, số nguyên và các biến chỉ đọc. Ngoài ra, nó mở rộng các đối số của nó, vì vậy những thứ như declare $name=1có thể.
choroba

Câu trả lời:


34

Từ help -m declare:

TÊN

    declare - Đặt giá trị và thuộc tính biến.

TÓM TẮC

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

SỰ MIÊU TẢ

    Đặt giá trị và thuộc tính biến.

    Khai báo các biến và cung cấp cho chúng các thuộc tính. Nếu không có TÊN nào được đưa ra, hãy hiển thị các thuộc tính và giá trị của tất cả các biến.

    Tùy chọn:

      -f
        hạn chế hành động hoặc hiển thị tên hàm và định nghĩa
      -F
        hạn chế chỉ hiển thị tên hàm (cộng với số dòng và tệp nguồn khi gỡ lỗi)
      -g
        tạo các biến toàn cục khi được sử dụng trong hàm shell; mặt khác bỏ qua
      -p
        hiển thị các thuộc tính và giá trị của từng TÊN

    Tùy chọn đặt thuộc tính:

      -a
        để tạo các mảng được lập chỉ mục TÊN (nếu được hỗ trợ)
      -A
        để tạo các mảng kết hợp TÊN (nếu được hỗ trợ)
      -i
        để làm cho TÊN có thuộc tính 'số nguyên'
      -l
        để chuyển đổi TÊN thành chữ thường
      -n
        làm cho NAME tham chiếu đến biến được đặt tên theo giá trị của nó
      -r
        để TÊN chỉ đọc
      -t
        để làm cho TÊN có thuộc tính 'dấu vết'
      -u
        để chuyển đổi TÊN thành chữ hoa
      -x
        để TÊN xuất

    Sử dụng ' +' thay vì ' -' sẽ tắt thuộc tính đã cho.

    Các biến có thuộc tính số nguyên có đánh giá số học (xem letlệnh) được thực hiện khi biến được gán một giá trị.

    Khi được sử dụng trong một hàm, đặt declareTÊN cục bộ, như với local lệnh. Các ' -g' tùy chọn ngăn chặn hành vi này.

    Trạng thái thoát:
    Trả về thành công trừ khi được cung cấp tùy chọn không hợp lệ hoặc xảy ra lỗi gán biến.

XEM THÊM

    bash (1)

THỰC HIỆN

    GNU bash, phiên bản 4.3.11 (1) -release (i686-pc-linux-gnu)
    Bản quyền (C) 2013 Free Software Foundation, Inc.
    Giấy phép GPLv3 +: GNU GPL phiên bản 3 trở lên <http://gnu.org/ giấy phép / gpl.html>


Vì vậy, declaređược sử dụng để thiết lập các giá trị và thuộc tính biến .

Hãy để tôi cho thấy việc sử dụng hai thuộc tính với một ví dụ rất đơn giản:

$ # 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

Từ ví dụ trên, tôi nghĩ bạn nên hiểu cách sử dụng declarebiến so với biến thông thường! Loại declareation này rất hữu ích trong các chức năng, các vòng lặp với kịch bản.

Cũng truy cập các biến Nhập: khai báo hoặc sắp chữ


vâng, "và thuộc tính" là điểm! đây là sự khác biệt
lovespring

Tuyệt quá! Tôi thích các ví dụ, cách tốt nhất để dạy / học. Cảm ơn!
Turkenh

1
Bạn cần biết "thuộc tính" là gì để hiểu câu trả lời này. Chúng là các thuộc tính của biến như 'số nguyên', 'mảng' hoặc 'chỉ đọc'.
Noumenon

11

abc=okgán một giá trị cho biến abc. declare abckhai báo một biến được gọi là abc. Hai có thể được kết hợp như declare abc=ok.

Trong bash, giống như các shell khác, các biến chuỗi và mảng không cần phải khai báo, do đó declarekhông cần thiết trừ khi bạn muốn vượt qua các tùy chọn, ví dụ declare -A abcđể tạo abcmột mảng kết hợp hoặc declare -rtạo một biến chỉ đọc. Tuy nhiên, bên trong một hàm, declaresẽ tạo ra sự khác biệt: nó làm cho biến là cục bộ của hàm, nghĩa là giá trị của biến bên ngoài hàm (nếu có) được giữ nguyên. (Trừ khi bạn sử dụng declare -g, làm cho biến không cục bộ; điều này hữu ích khi được kết hợp với các tùy chọn khác, ví dụ: declare -gAđể tạo một mảng kết hợp toàn cục trong một hàm.) Ví dụ:

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"

Đầu ra:

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

Một điều khác bạn có thể làm với declarenội dung là

Nội dung declarelà duy nhất để bash. Nó được truyền cảm hứng mạnh mẽ và rất gần với typesetnội dung của ksh , và bash cung cấp typesetnhư một từ đồng nghĩa của declaretính tương thích. (Tôi không biết tại sao bash không chỉ gọi nó typeset). Có một từ đồng nghĩa thứ ba , local. Ngoài ra, cũng exportgiống như declare -x, một lần nữa cho khả năng tương thích (với mọi vỏ kiểu Bourne).


Đúng! 'và tùy chọn' là điểm. Nếu tôi thiết kế bash, tôi sẽ để hành vi "khai báo" thực hiện một số điều trong các điều kiện khác nhau. Điều này làm cho mọi thứ đơn giản.
lovespring

Câu trả lời tốt đẹp. Một câu hỏi nữa, cái nào trong số đó export, localdeclarecó tương thích nhất với các shell khác không?
0xc0de

1
@ 0xc0de exporttồn tại trong tất cả các biến thể của sh. localchỉ tồn tại trong bash và zsh, declarechỉ trong bash. typesettồn tại trong ksh, bash và zsh.
Gilles 'SO- ngừng trở nên xấu xa'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.