1

I am working trough some legacy code which does not work, I came across a part that is causing problems. I was hoping some one could help me out and fill me in on what is the exact functionality of this small part of the script and what could cause it to fail/not execute. If I run the first .sql file on command line, everything works great and I am using the same sql-logins as the script.

I have an update.sh file, which is run every night and takes care of updating customer info. How ever when we add customers to the file where it reads the data it fails to generate new database and stored procedure instances.

code snippet:

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

If I understand correctly the first part -i means modify(change database in use in the script) create_tk.sql.

/s means that it is done recursively to each company

/1i means keep the tk[0-9]*;/tk$company_id; part of the string? and Insert the content?

/gi something to do with hold and pattern spaces? and Insert the content?

I would appreciate it really much if someone could clarify the exact meaning of this snippet and point out what could cause not being able to fulfill its function.

Thanks for the help everyone.

1
  • Try putting the -p outside the quotes as in mysql -h $mysql_host -u $mysql_id -p $mysql_pwd. Also quoting mysql_pwd is sending the literal $mysql_pwd as the password.
    – eyoung100
    Sep 16, 2014 at 13:57

3 Answers 3

3

I have an update.sh file, which is run every night

I read that as "I'm launching this via cron". A very common issue people have with cron is that they make expectations about the environment the script runs in. They assume the script will run in their home directory.

That's exactly what you're doing. All your sed commands use relative paths so they work when you're in the correct directory... But is cron in the same directory? Probably not.

You have a choice of fixes here:

  1. Use absolute paths in all your scripts commands like /home/bob/dir/file
  2. Make your script cd into the right directory (use an absolute path) at the top of the script.
  3. Make your cron command cd into the correct directory before operating, eg:

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

On the comment about permissions, if you don't have write permissions to do an in-place sed, you could just output to somewhere where you do have write permissions, eg:

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#

Or you could actually just pipe from the sed into 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"

These approaches won't change the original resources/sql/*.sql files so if you need to edit those, you need to fix your permissions issues (whatever they are; use stat filename to see what's going on)

2
  • Thank you. Your explanation was great and I took a look at the cron-file, but it seems to be in order # 07 08 * * * cd /my/drupal/directory/where/cript/lies && bash /my/drupal/directory/where/script/lies/update.sh Sep 17, 2014 at 6:43
  • Also I should clarify that earlier in the script there are run stored procedures (on another server) and the query out to .txt -files and this works. For me (this is not really my area of expertise, far from it) it seems like it would have something to do with rights? Sep 17, 2014 at 6:48
1

@Oli told you why it is probably failing so I'll just explain the sed code:

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

The s/PATTERN/REPLACEMENT/FLAGS is the substitution operator. It will replace PATTERN with REPLACEMENT. The FLAGS (for example, g in s///g) can modify its behavior. Here, the flags are N (1 in your example) which means "Replace only the Nth match of PATTERN (this is strange, the N flag is normally used to replace the Nth match where N is greater then 1. I don't see why it's needed here, sed will replace only the first match by default). And i which makes the match case-insensitive.

Your second sed has the flags g and i. The i is case-insensitive matching and the g makes the replacement global, it will be applied to all matches in the current line. Without it, only the first would be replaced which is why I don't see the point of the 1 flag in the previous example.

1

You're not totally right regarding the meaning the sed options. Let me first explain them then we will understand what your code is doing.

  • Option -i means : instead of displaying the result of the sed processing on the terminal, write it to the file.
  • s/ syntax is s/regexp/replacement/. It means sed will substitute the strings matching the regular expression (regexp) by the content of replacement.

The characters after the last / are modifiers, they affect how sed will process the lines :

  • /g means "Apply the replacement to all matches to the regexp, not just the first."
  • /1 means "Only replace the first match of the regexp."
  • /i for case insensitive

/gi and /1i are combinations of those.

So in your code, this line :

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

would translate (read as one sentence) :

  • In the resources/sql/create_tk.sql file (-i option)
  • substitute (s/)
  • all strings (/g)
  • starting with tk (upper or lower characters /i), eventually followed by a number, then followed by a semi-colon
  • by the string tk followed by the content of variable $company_id followed by a semi-colon

Source : https://www.gnu.org/software/sed/manual/html_node/The-_0022s_0022-Command.html and sed's man page.

1
  • Thank you for clarifying this to me. It was very helpful Sep 17, 2014 at 6:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .