Não é possível executar sed no script bash

1

Estou trabalhando em algum código legado que não funciona, me deparei com uma parte que está causando problemas. Eu estava esperando que alguém pudesse me ajudar e me informar sobre qual é a funcionalidade exata dessa pequena parte do script e o que poderia fazer com que ele falhasse / não fosse executado. Se eu executar o primeiro arquivo .sql na linha de comando, tudo funciona muito bem e estou usando os mesmos logins sql que o script.

Eu tenho um arquivo update.sh, que é executado todas as noites e cuida da atualização das informações do cliente. No entanto, quando adicionamos clientes ao arquivo onde ele lê os dados, ele não gera novas instâncias de banco de dados e de procedimento armazenado.

snippet de código:

#!/bin/bash

mysql_host="localhost"
mysql_id="root"
mysql_pwd="sudopwd"

read_dom () {
    local IFS=\>
    read -d \< ENTITY CONTENT
}

    .
    Some functioning code   
    .
    .
    Here is the part that does not work
        sed -i "s/tk[0-9]*;/tk$company_id;/1i" resources/sql/create_tk.sql
        mysql -h $mysql_host -u $mysql_id "-p$mysql_pwd" < resources/sql/create_tk.sql

        sed -i "s/tk[0-9]*/tk$company_id/gi" resources/sql/load_data_tk.sql
        mysql -h $mysql_host -u $mysql_id "-p$mysql_pwd"< resources/sql/load_data_tk.sql

    fi
done < info.xml

EN_MO=$(date +%s)
DIFF_MO=$[$EN_MO-$ST_MO] 
C_DATE=$(date +"%Y%m%d%H%M")

Se eu entendi corretamente a primeira parte -i significa modificar (alterar banco de dados em uso no script) create_tk.sql.

/ s significa que é feito recursivamente para cada empresa

/ 1i significa manter o tk [0-9] * / tk $ company_id; parte da corda? e insira o conteúdo?

/ gi algo a fazer com espaços de espera e padrão? e insira o conteúdo?

Eu apreciaria muito se alguém pudesse esclarecer o significado exato deste trecho e apontar o que poderia causar o não cumprimento de sua função.

Obrigado pela ajuda de todos.

    
por user1054844 16.09.2014 / 15:40

3 respostas

3
  

Eu tenho um arquivo update.sh, que é executado todas as noites

Eu li isso como "Estou lançando isso via cron". Um problema muito comum que as pessoas têm com o cron é que elas fazem expectativas sobre o ambiente em que o script é executado. Eles assumem que o script será executado em seu diretório pessoal.

Isso é exatamente o que você está fazendo. Todos os seus comandos sed usam caminhos relativos para funcionar quando você está no diretório correto ... Mas é cron no mesmo diretório? Provavelmente não.

Você tem uma escolha de correções aqui:

  1. Use caminhos absolutos em todos os seus comandos de script, como /home/bob/dir/file
  2. Transforme seu script cd no diretório correto (use um caminho absoluto) na parte superior do script.
  3. Faça seu comando cron cd no diretório correto antes de operar, por exemplo:

    00 00 * * *   cd /home/bob && ./update.sh
    

No comentário sobre permissões, se você não tiver permissões de gravação para fazer um sed no local, você poderia simplesmente enviar para algum lugar onde você tem permissões de gravação, por exemplo:

sed "s/tk[0-9]*;/tk$company_id;/1i" resources/sql/create_tk.sql > $HOME/temp.sql
mysql -h $mysql_host -u $mysql_id "-p$mysql_pwd" < $HOME/temp.sql
rm $HOME/temp.sql#

Ou você pode, na verdade, apenas canalizar do sed para o mysql :

sed "s/tk[0-9]*;/tk$company_id;/1i" resources/sql/create_tk.sql \
| mysql -h $mysql_host -u $mysql_id "-p$mysql_pwd"

Essas abordagens não alteram os arquivos resources/sql/*.sql originais, portanto, se você precisar editá-los, será necessário corrigir seus problemas de permissões (sejam eles quais forem; use stat filename para ver o que está acontecendo)

    
por Oli 16.09.2014 / 16:07
1

@Oli disse porque provavelmente está falhando, então vou explicar o código sed :

sed -i "s/tk[0-9]*;/tk$company_id;/1i"

O s/PATTERN/REPLACEMENT/FLAGS é o operador de substituição. Ele substituirá PATTERN por REPLACEMENT . O FLAGS (por exemplo, g in s///g ) pode modificar seu comportamento. Aqui, os sinalizadores são N ( 1 em seu exemplo), o que significa "Substituir apenas a enésima coincidência de PATTERN (isso é estranho, o sinal N é normalmente usado para substituir a enésima coincidência onde N é maior" então 1. Eu não vejo porque é necessário aqui, sed irá substituir apenas a primeira partida por padrão) E i que torna a partida sem distinção entre maiúsculas e minúsculas.

Seu segundo sed tem os sinalizadores g e i . A i é uma correspondência sem distinção entre maiúsculas e minúsculas e o g torna a substituição global, será aplicada a todas correspondências na linha atual. Sem ele, apenas o primeiro seria substituído, e é por isso que não vejo o ponto do 1 no exemplo anterior.

    
por terdon 16.09.2014 / 16:27
1

Você não está totalmente certo em relação ao significado das opções de sed. Deixe-me primeiro explicá-los, então vamos entender o que seu código está fazendo.

  • A opção -i significa: em vez de exibir o resultado do processamento sed no terminal, grave-o no arquivo.
  • A sintaxe s / é s / regexp / replacement / . Isso significa que o sed substituirá as strings que correspondem à expressão regular ( regexp ) pelo conteúdo de substituição .

Os caracteres após o último / são modificadores, eles afetam o modo como o sed processará as linhas:

  • / g significa "Aplique a substituição a todas as correspondências ao regexp, não apenas ao primeiro."
  • / 1 significa "Substitua apenas a primeira correspondência da expressão regular".
  • / i para maiúsculas e minúsculas

/ gi e / 1i são combinações desses.

Então, no seu código, esta linha:

sed -i "s/tk[0-9]*;/tk$company_id;/gi" resources/sql/create_tk.sql

traduziria (leia como uma frase):

  • No arquivo resources / sql / create_tk.sql (opção -i )
  • substitute ( s / )
  • todas as strings ( / g )
  • começando com tk (caracteres superiores ou inferiores / i ), eventualmente seguido por um número, seguido de um ponto e vírgula
  • pela string tk seguida pelo conteúdo da variável $ company_id seguido por um ponto e vírgula

Fonte: link e a página de manual do sed.

    
por syldes 16.09.2014 / 16:44