web-dev-qa-db-fra.com

Impossible d'exécuter sed sur le script bash

Je travaille à travers un code hérité qui ne fonctionne pas, je suis tombé sur une partie qui pose problème. J'espérais que quelqu'un pourrait m'aider et me renseigner sur la fonctionnalité exacte de cette petite partie du script et sur ce qui pourrait provoquer son échec/son exécution. Si j'exécute le premier fichier .sql sur la ligne de commande, tout fonctionne très bien et j'utilise les mêmes connexions sql que le script.

J'ai un fichier update.sh, qui est exécuté tous les soirs et s'occupe de la mise à jour des informations client. Cependant, lorsque nous ajoutons des clients au fichier où il lit les données, il ne parvient pas à générer une nouvelle base de données et des instances de procédure stockée.

extrait de code:

#!/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")

Si je comprends bien la première partie - i signifie modifier (changer la base de données utilisée dans le script) create_tk.sql.

/ s signifie que cela se fait récursivement pour chaque entreprise

/ 1i signifie garder le tk [0-9] *;/tk $ company_id; une partie de la chaîne? et insérer le contenu?

/ gi quelque chose à voir avec les espaces d'attente et de motif? et insérer le contenu?

J'apprécierais beaucoup que quelqu'un puisse clarifier la signification exacte de cet extrait et souligner ce qui pourrait empêcher de remplir sa fonction.

Merci à tous pour l'aide.

1
user1054844

J'ai un fichier update.sh, qui est exécuté tous les soirs

J'ai lu cela comme "je lance ceci via cron". Un problème très courant avec cron est qu'ils font des attentes concernant l'environnement dans lequel le script s'exécute. Ils supposent que le script s'exécutera dans leur répertoire personnel.

C'est exactement ce que tu fais. Toutes vos commandes sed utilisent des chemins relatifs afin qu'elles fonctionnent lorsque vous êtes dans le bon répertoire ... Mais cron est-il dans le même répertoire? Probablement pas.

Vous avez un choix de correctifs ici:

  1. Utilisez des chemins absolus dans toutes vos commandes de scripts comme /home/bob/dir/file
  2. Faites votre script cd dans le bon répertoire (utilisez un chemin absolu) en haut du script.
  3. Placez votre commande cron cd dans le bon répertoire avant de procéder, par exemple:

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

Sur le commentaire sur les autorisations, si vous n'avez pas d'autorisations d'écriture pour faire un sed sur place, vous pouvez simplement sortir vers un endroit où vous avez des autorisations d'écriture, par exemple:

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 vous pouvez en fait simplement diriger du sed vers 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"

Ces approches ne changeront pas l'original resources/sql/*.sql fichiers, donc si vous devez les modifier, vous devez corriger vos problèmes d'autorisations (quels qu'ils soient; utilisez stat filename pour voir ce qui se passe)

3
Oli

@Oli vous a expliqué pourquoi il échoue probablement, je vais donc vous expliquer le code sed:

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

Le s/PATTERN/REPLACEMENT/FLAGS est l'opérateur de substitution. Il remplacera PATTERN par REPLACEMENT. FLAGS (par exemple, g dans s///g) peut modifier son comportement. Ici, les drapeaux sont N (1 dans votre exemple) qui signifie "Remplacer uniquement la Nième correspondance de MOTIF (cela est étrange, l'indicateur N est normalement utilisé pour remplacer la Nième correspondance où N est supérieur à 1. I Je ne vois pas pourquoi cela est nécessaire ici, sed ne remplacera que la première correspondance par défaut.) Et i ce qui rend la correspondance insensible à la casse.

Votre deuxième sed a les drapeaux g et i. i est une correspondance insensible à la casse et g rend le remplacement global, il sera appliqué aux correspondances all dans la ligne courante. Sans cela, seul le premier serait remplacé, c'est pourquoi je ne vois pas l'intérêt du 1 flag dans l'exemple précédent.

1
terdon

Vous n'avez pas tout à fait raison concernant la signification des options sed. Permettez-moi d'abord de les expliquer, nous comprendrons ce que fait votre code.

  • L'option - i signifie: au lieu d'afficher le résultat du traitement sed sur le terminal, écrivez-le dans le fichier.
  • s/ la syntaxe est s/regexp/remplacement /. Cela signifie que sed remplacera les chaînes correspondant à l'expression régulière ( regexp) par le contenu de remplacement .

Les caractères après le dernier / sont des modificateurs, ils affectent la façon dont sed traitera les lignes:

  • /g signifie "Appliquer le remplacement à toutes les correspondances à l'expression rationnelle, pas seulement la première".
  • /1 signifie "Remplacer uniquement la première correspondance de l'expression rationnelle".
  • /i pour la casse

/gi et /1i sont des combinaisons de ceux-ci.

Donc, dans votre code, cette ligne:

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

traduirait (lu comme une phrase):

  • Dans le fichier ( resources/sql/create_tk.sql ( - i ) )
  • substitut ( s/)
  • toutes les chaînes (/g )
  • commençant par tk (caractères supérieurs ou inférieurs /i ), éventuellement suivis par un nombre, suivi d'un point-virgule
  • par la chaîne tk suivie du contenu de la variable $ company_id suivie de un point-virgule

Source: https://www.gnu.org/software/sed/manual/html_node/The-_0022s_0022-Command.html et la page de manuel de sed.

1
syldes