O script Shell é executado de maneira diferente com base no diretório de trabalho.

1

Eu tenho um script que é executado de forma diferente com base no diretório de trabalho atual. Basicamente, ele processa um arquivo .ini e obtém parâmetros dele e executa o backup do mysql.

O script está sendo executado como usuário root.

Quando eu o executo com o diretório de trabalho como / root. Ele sai com erro. Os parâmetros do arquivo .ini não são refletidos no script.

Quando eu faço cd / então executo, funciona bem.

Aqui está a função que parece falhar.

get_param()
{

 for line in 'cat ${PARAMETERSFILE}'
 do

    if [ "${ISFOUND}" != "true" -a "'echo ${line} | grep ${STAG} | grep -v grep | wc -l'" == "1" ]
   then
     ISFOUND="true"
fi

    if [ "${ISFOUND}" == "true" -a "'echo ${line} | grep ${ETAG} | grep -v grep | wc -l'" == "1" ]
  then
     ISFOUND="false"
fi
if [ "${ISFOUND}" == "true" -a "'echo ${line} | grep ${STAG} | grep -v grep | wc -l'" != "1" ]
   then
    key="'echo ${line} | sed 's/=/ /' | awk '{print $1}''"
    val="'echo ${line} | sed 's/=/ /' | awk '{print $2}''"
    cmd="${key}=\"${val}\""
    eval ${cmd}
fi
 done
}

Algumas variáveis são as seguintes:

STAG="\[backup\]"
ETAG="\/backup\]"
ISFOUND="false"

O arquivo ini é como abaixo

[help]
 backupdir="Backup Home Directory "
 user="MySQL Database  Username"
 password="MySQL Database Password"
 retentioPeriodMinutes="Retention Period of Backup (e.g. 1440= 1 day)"
 memory="Dedicated RAM (Mbyte)"
[/help]

[backup]
 backupdir=/opt/backupdb
 user="root"
 password="xyz"
[/backup]

[restore]
 backupdir=/opt/backupdb
 user="root"
 password="xyz"
 memory="1024"
[/restore]

[houseKeeping]
 backupdir=/opt/backupdb
 retentioPeriodMinutes=10080
[/houseKeeping]

Abaixo está a saída durante a execução com sh -xv. Parece pipe não está funcionando como deveria quando o diretório atual é / root

+ for line in ''cat ${PARAMETERSFILE}''
echo ${line} | grep ${STAG} | grep -v grep | wc -l
++ grep '\[backup\]'
++ grep -v grep

++ wc -l
+ '[' false '!=' true -a 0 == 1 ']'
echo ${line} | grep ${ETAG} | grep -v grep | wc -l
++ grep '\/backup\]'
++ echo '[help]'
++ grep -v grep
++ wc -l

+ '[' false == true -a 0 == 1 ']'
echo ${line} | grep ${STAG} | grep -v grep | wc -l

++ grep -v grep
++ grep '\[backup\]'
++ echo '[help]'
++ wc -l

Aqui está a mesma saída quando o diretório de trabalho é /

+ for line in ''cat ${PARAMETERSFILE}''
echo ${line} | grep ${STAG} | grep -v grep | wc -l
++ grep '\[backup\]'
++ grep -v grep
++ echo '[help]'

+ '[' false '!=' true -a 0 == 1 ']'
echo ${line} | grep ${ETAG} | grep -v grep | wc -l
++ grep '\/backup\]'

++ grep -v grep
++ wc -l
++ echo '[help]'
+ '[' false == true -a 0 == 1 ']'
echo ${line} | grep ${STAG} | grep -v grep | wc -l
++ echo '[help]'
++ grep -v grep
++ grep '\[backup\]'

++ wc -l
    
por Anand S 03.03.2015 / 07:29

1 resposta

0

Eu vejo pelo menos um erro que poderia explicar o problema. Eu não revisei seu roteiro em detalhes. Veja o que esta linha faz:

  for line in 'cat ${PARAMETERSFILE}'
  1. Pegue o valor da variável PARAMETERSFILE .
  2. Dividir esse valor no espaço em branco - isso resulta em uma única palavra se o valor contiver apenas caracteres "comuns".
  3. Execute expansão de nome de arquivo a.k.a. globting em cada palavra. Isso ainda resulta em uma única palavra se o valor da variável contiver apenas caracteres "comuns".
  4. Execute cat no arquivo especificado.
  5. Leia a saída de cat , pois esta é uma substituição de comando
  6. Dividir a saída do comando no espaço em branco. Desta vez, a string a dividir contém muitas novas linhas e alguns espaços; as palavras resultantes são [help] , backupdir="Backup , Home , Directory , " , user="MySQL , Database , Username" ,…
  7. Execute expansão de nome de arquivo a.k.a. globando em cada palavra.

Desta vez, algumas das palavras contêm caracteres curinga, pelo que serão interpretadas como um padrão glob. Se o padrão não corresponder a nenhum arquivo, ele será deixado como está. Se o padrão corresponder a pelo menos um arquivo, ele será substituído pela lista de arquivos correspondentes.

Uma string como [help] é um padrão glob que quatro possíveis correspondem a nomes de arquivos de um caractere: h , e , l , p . Portanto, se você executar o script em um diretório que não contenha nenhum arquivo por nenhum desses nomes, a palavra [help] permanecerá intacta, mas se, e. o diretório atual contém um arquivo chamado h , em seguida, [help] é substituído por h .

for line in … não divide a entrada em linhas. A maneira mais fácil de fazer isso é

while IFS= read -r line; do
  …
done <"$PARAMETERSFILE"

IFS= read -r line lê exatamente uma linha, sem caractere diferente de nova linha sendo especial. Se você deseja remover espaços em branco iniciais e finais, remova IFS= . Se você quiser permitir que a barra invertida sirva como um caractere de continuação de linha (por exemplo, a barra invertida no final de uma linha ignora a nova linha seguinte), remova -r .

    
por 04.03.2015 / 00:08