Como posso imprimir apenas variáveis definidas dentro do meu script de shell?

3

Vamos supor um pouco script de shell como:

#!/bin/bash 
a=3
b=7
set -o posix
set

Nesse caso, a execução da variável set ou de alguns outros comandos para imprimir variáveis de ambiente ( env , declare ... etc) gera minha a e b variáveis, além de um lote de variáveis (e funções) do ambiente ( PATH , PWD , TEMP ... etc).

Existe uma maneira de imprimir apenas as variáveis que foram definidas durante o corpo do script ?

    
por Sopalajo de Arrierez 09.12.2014 / 08:28

6 respostas

1

Uma solução usando comm com base no armazenamento de todas as variáveis antes e depois:

#!/bin/bash 

# Storing variables before:
set -o posix
set > $TMP/VariablesBefore.txt
sort $TMP/VariablesBefore.txt -o $TMP/VariablesBeforeSorted.txt

a=3
b=7

# Storing variables after:
set > $TMP/VariablesNow.txt
sort $TMP/VariablesNow.txt -o $TMP/VariablesNowSorted.txt

# Computing differences:
echo "The variables inside the script are: "
comm -3 $TMP/VariablesBeforeSorted.txt $TMP/VariablesNowSorted.txt

Bem, ainda existem algumas variáveis restantes como _ ou BASH_LINENO , mas esta é a aposta que eu alcancei.

Note that this solution could not work in all cases, for example variables very long (KB), with new line codes, or variables including variable names. Thanks, MikeServ, for pointing.

    
por 09.12.2014 / 09:14
1

Você pode armazenar a lista de variáveis no início do script e compará-la com o valor em algum lugar durante o script. Tenha em atenção que a saída de comandos como set não foi criada para ser inequívoca: algo como set | sed 's/=.*//' não funciona com variáveis cujos valores contenham novas linhas. (No bash, ele realmente serve para variáveis de string, mas não para arrays, e também exibe o código de função). Eu acho que o seguinte trecho lista de forma confiável as variáveis atualmente definidas (em ordem alfabética, para inicializar):

variables=$(tmp=$(declare -p +F); declare () { echo "${2%%=*}"; }; eval "$tmp")

Assim, defina initial_variables=… no início do script e compare com o valor mais recente. Você pode usar algo diferente de echo para atuar diretamente na lista.

initial_variables=" $(tmp=$(declare -p +F); declare () { echo "${2%%=*}"; }; eval "$tmp") "
…
( tmp=$(declare -p +F)
  declare () {
    case "$initial_variables" in
      *" $2 "*) :;; # this variable was present initially
      *) eval "set -- \"\$$2\" \"\\""; echo "locally defined $2=$1";;
    esac
  }
)
    
por 10.12.2014 / 02:02
1

Eu trapaceei: simplesmente renomeiei as variáveis que eu não queria listadas para algo que começa com as letras "aaa" (por exemplo, as variáveis que eu criei de outro arquivo), e então chamei o builtin compgen -v comando. Então eu classifiquei pelo número de variáveis que eu sabia que existiam no meu script.

Por exemplo, eu provei de outro arquivo duas variáveis cujos nomes começaram com aaa, e eu tinha três variáveis aleatoriamente nomeadas no meu script (a primeira letra variava de A a Z ) e eu estava capaz de listar apenas essas três variáveis na saída, colocando este comando simples no meu script:

compgen -v | tail -n 3

EDITAR:
se eu não soubesse exatamente quantas variáveis eu tinha no meu script: então eu poderia fazer algo assim:

compgen -v | awk '$0 == "aaauser" {i=1;next};i && i++ <= 100'

onde aaauser é a variável última ordem alfabética que eu provei do meu outro arquivo. Você poderia aplicar isso a qualquer variável conhecida.

    
por 11.10.2017 / 17:03
0

Aqui está um meio portátil de obter uma lista ordenada de todos os nomes de nomes atualmente definidos:

v(){ set "${IFS+IFS=\}" "$IFS"; unset IFS
     set  $(set|sed -n '/^[_[:alpha:]][[:alnum:]]*=/s/=.*//p'|sort -u) "$@"
     while [ "$#" -gt 2 ] 
     do    eval '[ "${'$1'+1}" = 1 ]' && 
           echo "$1"; shift
     done; eval "$1"
}

Essa lista é echo ed para o stdout de v() - um nome por linha. Como é sort ed, é um bom candidato para comparação posterior com uma lista gerada de forma semelhante, como você faria com comm ou similar. A lista exclui intencionalmente $IFS - e isso é porque - setado ou não - $IFS é sempre em vigor e assim deve ser dado de qualquer maneira em tal lista. Isso poderia ser alterado como:

set "${IFS+IFS=\}" "$IFS"; IFS='
'; set $(set|... 

... mas isso sempre só inclui em uma lista, seja ela definida ou não - o que me traz de volta ao meu ponto anterior ...

    
por 10.12.2014 / 02:57
0

O shell Bash carregará /etc/profile , ~/.bash_profile , ~/.bash_login , ~/.profile na ordem.

Qualquer coisa que não esteja definida acima pode ser assumida com segurança para ser definida pelo seu script.

    
por 11.10.2017 / 18:04
0

Uma estratégia de 2 linhas usando comm , compgen -v e Substituição de Processo ...

ENVVARS="$(compgen -v)"
    :
  <script>
    :
comm -1 -3 <(sort <<< "$ENVVARS") <(compgen -v | sort)

De comm --help ...

Usage: comm [OPTION]... FILE1 FILE2

Compare sorted files FILE1 and FILE2 line by line.

With no options, produce three-column output.  Column one contains
lines unique to FILE1, column two contains lines unique to FILE2, and
column three contains lines common to both files.

    -1              suppress lines unique to FILE1
    -2              suppress lines unique to FILE2
    -3              suppress lines that appear in both files

O comando comm nos permite "subtrair" o conjunto de variáveis de ambiente passadas para o script do conjunto total presente no final do script para nos deixar apenas aqueles criados pelo script.

As opções -1 e -3 descartam todas menos as variáveis criadas neste script (que são linhas no "arquivo 2"). Bash Process Substituição <(...) é usada para listar e classificar as variáveis e, em seguida, tratar a saída como um arquivo.

Observe que as variáveis declaradas locais para funções não são incluídas, pois estão fora do escopo do script principal.

A mesma técnica pode ser usada para listar variáveis criadas dentro de uma função. No entanto, a convenção de nomear essas variáveis começando com o sublinhado (_) e adicionando o prefixo de sublinhado à chamada compgen nesses casos pode ser mais desejável ...

LOCALVARS="$(compgen -v _)"
    
por 20.01.2018 / 22:26