Variáveis de somente leitura são aquelas que não podem ser modificadas. Seriam algo como as constantes da maioria das linguagens de programação.
Para criarmos variáveis comuns ou vetores de somente leitura, podemos usar dois comandos - que são built-in's do bash -, que são o declare e o readonly.
O declare cria uma variável já com alguns atributos, como ser array ou não, ser de somente leitura, etc:
$ declare -ar vetor='([10]="Linux" [20]="Unix")'
Exibindo o vetor:
$ echo ${vetor[@]}
Linux Unix
Assim, vetor é um array (-a) de somente leitura (-r).
Observação: Se você não usar o parâmetro "-a", não será criado um vetor, mas sim uma variável normal:
$ declare -r vetor='([10]="Linux" [20]="Unix")'
$ echo ${vetor[@]}
([10]="Linux" [20]="Unix")
OBS:
- Variáveis também funcionam normalmente como elementos, usando essa sintaxe. Por exemplo, poderíamos atribuir à um elemento o valor de $UID, ou $(uname).
- Essa é só uma sintaxe de atribuição de elementos à um vetor. Também é possível usar a maneira tradicional:
$ declare -r teste=(Elem1 Elem2)
Se tentarmos modificar o valor de vetor:
$ vetor[20]=Windows
bash: vetor: readonly variable
Ou, pegamos uma variável do sistema (ou qualquer outra) e a transformamos em read-only:
$ readonly -p PATH
Tentando modificá-la...
$ export PATH=$PATH:/opt/gnome/bin
bash: PATH: readonly variable
Isso é útil caso você não queira que algum usuário modifique o seu PATH.
E também se tentarmos apagar uma variável nativamente de somente-leitura:
$ unset UID
bash: unset: UID: cannot unset: readonly variable
OBS: Essa variável UID diz que usuário você é. E há uma razão simples para ela ser de somente-leitura: se não fosse, bastaria um "UID=0" para que você adquirisse privilégios de root!
Mas como fazer a variável voltar ao modo leitura-escrita? Não faço a mínima idéia...
Para exibirmos quais são as variáveis que são somente leitura, utilizamos o comando readonly sem parâmetros:
$ readonly
declare -ar BASH_VERSINFO='([0]="3" [1]="1" [2]="17" [3]="2" [4]="release" [5]="i486-slackware-linux-gnu")'
declare -ir EUID="1000"
declare -rx PATH="/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/games:/opt/kde/bin: /opt/rox/bin:/opt/xaralx/bin:/opt/www/htdig/bin:/usr/lib/java/bin:/usr/lib/java/jre/bin: /usr/lib/java/bin:/usr/lib/java/jre/bin:/opt/kde/bin:/usr/lib/qt/bin:/usr/share/texmf/bin: .:/home/tenchi/.local/bin:/opt/rox/bin/:/opt/qemu/bin/"
declare -ir PPID="15847"
declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history: interactive-comments:monitor"
declare -ir UID="1000"
declare -ar vetor='([10]="Linux" [20]="Unix")'