У сценаріїх bash, чим відрізняється оголосити від звичайної змінної?


43

У сценаріїх bash:

ми створюємо змінну, просто називаючи її:

abc=ok

або ми можемо використовувати declare

declare abc=ok

яка різниця?

і чому bash робить так багато способів створити змінну?


6
При використанні у функції declareробить NAMEs локальними, як і в localкоманді. Цей -gваріант пригнічує таку поведінку. Див help declare.
Кіра

2
declareдозволяє створювати асоціативні масиви, цілі числа та змінні лише для читання. Крім того, він розширює свої аргументи, тому подібні речі declare $name=1можливі.
choroba

Відповіді:


34

Від help -m declare:

ІМ’Я

    declare - Встановити змінні значення та атрибути.

СИНОПИС

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

ОПИС

    Встановити змінні значення та атрибути.

    Оголосіть змінні та надайте їм атрибути. Якщо імена NAME не вказані, відобразіть атрибути та значення всіх змінних.

    Параметри:

      -f
        обмежити дію чи показ лише іменами та визначеннями функцій
      -F
        обмежити відображення лише іменами функцій (плюс номер рядка та вихідний файл при налагодженні)
      -g
        створювати глобальні змінні при використанні функції оболонки; інакше ігнорується
      -p
        відобразити атрибути та значення кожного імені

    Параметри, які встановлюють атрибути:

      -a
        робити масиви з індексованими NAMEs (якщо вони підтримуються)
      -A
        створювати асоціативні масиви NAME (якщо вони підтримуються)
      -i
        щоб NAME мали атрибут 'integer'
      -l
        конвертувати NAMEs у малі регістри при призначенні
      -n
        зробити NAME посиланням на змінну, названу її значенням
      -r
        щоб зробити NAMEs лише читати
      -t
        щоб NAME мали атрибут "слід"
      -u
        конвертувати NAMEs у верхній регістр при призначенні
      -x
        щоб експортувати NAMEs

    Використання ' +' замість ' -' вимикає даний атрибут.

    Змінні з цілим атрибутом мають арифметичну оцінку (див. letКоманду), яка виконується, коли змінній присвоюється значення.

    При використанні у функції declareробить NAMEs локальними, як і в local команді. Варіант ' -g' пригнічує таку поведінку.

    Статус виходу:
    Повертає успіх, якщо не введено недійсний параметр або не виникає помилка присвоєння змінної.

ДИВИТИСЯ ТАКОЖ

    баш (1)

ВПРОВАДЖЕННЯ

    GNU bash, версія 4.3.11 (1) -випуск (i686-pc-linux-gnu)
    Copyright (C) 2013 Free Software Foundation, 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змінної над звичайною змінною! Цей тип дії declareкорисний для функцій, циклів із написанням сценарію.

Також відвідайте введення змінних: оголосити або набрати


так, "атрибути" - справа! це різниця.
lovepring

Чудово! Я люблю приклади, найкращий спосіб вчити / вчитися. Дякую!
туркен

1
Вам потрібно знати, що таке «атрибути», щоб зрозуміти цю відповідь. Вони є властивостями змінної на зразок "ціле число", "масив" або "лише для читання".
Номенон

11

abc=okприсвоює значення змінній abc. declare abcоголошує змінну, що називається abc. Ці два можуть поєднуватися як declare 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

Ще одна річ, яку ви можете зробити з declareвбудованим - це

declareВбудований є унікальною для Баша. Він натхненний і дуже близький до typesetвбудованої програми ksh , а bash - typesetце синонім declareсумісності. (Я не знаю, чому Баш не просто так зателефонував typeset). Там ще третій синонім local. Є також exportте ж саме declare -x, що і для сумісності (з кожною оболонкою в стилі Борна).


так! точкою є "і варіант". ps, якщо я спроектую баш, я дозволю поведінці "оголосити" робити якусь річ у різних умовах. це робить прості речі.
lovepring

Гарна відповідь. Подальше питання, який з них є export, localа declareтакож найбільш сумісний з іншими оболонками?
0xc0de

1
@ 0xc0de exportіснує у всіх варіантах sh. localіснує тільки в bash і zsh, declareтільки в bash. typesetіснує в ksh, bash і zsh.
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.