{"id":3404,"date":"2014-07-04T18:10:29","date_gmt":"2014-07-04T18:10:29","guid":{"rendered":"http:\/\/really.zonky.org\/?p=3404"},"modified":"2014-07-04T18:29:38","modified_gmt":"2014-07-04T18:29:38","slug":"safely-running-mysql-commands-as-a-batch-file","status":"publish","type":"post","link":"https:\/\/really.zonky.org\/?p=3404","title":{"rendered":"Safely Running MySQL Commands as a Batch File"},"content":{"rendered":"<p>Well, relatively safely anyway.<\/p>\n<p>The other day I felt the urge to knock up some SQL to clean up a MySQL table I&#8217;m responsible for. So I got the SQL prepared, but then needed to find out how to run this as a cron job (or batch file if you prefer). This was because I wanted to run the job on a regular and frequent basis; and I&#8217;m too lazy to sit around with a stopwatch running the same command every 15 minute.<\/p>\n<p>I came up with a method that I knew wasn&#8217;t recommended &#8211; as it said so in the manual. The method involved passing the contents of a file to the command line (i.e.\u00a0<em>mysql -u root -p$(cat somefile)<\/em>.\u00a0And today I decided to have a look around to see if there was a better way.<\/p>\n<p>It turns out that much of the most visible advice on the Internet is\u00a0<em>wrong<\/em>. It all suggests using the\u00a0<em>-p<\/em> option where the account password is visible in the process table (i.e. you can read it with\u00a0<em>ps aux<\/em>). If you can\u00a0<em>guarantee<\/em> that no rogue person will be able to login to your server and read the process table, then you are safe; and I would like to ask how you can achieve the impossible.<\/p>\n<p>Putting a password in a file (as suggested below) is at least somewhat better, but it would be nice if MySQL were to offer something a bit more sophisticated.<\/p>\n<p>However, on to the method.<\/p>\n<p>The first step is to create an options file, and make sure that it is readable only by the current user :-<\/p>\n<pre>\r\n$ touch mysql-options-root.cnf\r\n$ chmod go= mysql-options-root.cnf\r\n<\/pre>\n<p>Once securely created, you can edit the file and add the relevant options :-<\/p>\n<pre>\r\n[client]\r\npassword=do-you-really-think-i-would-tell-the-internet-what-my-mysql-root-password-is?\r\n<\/pre>\n<p>That list of options is fairly minimal; it only specifies the password to use. You can add additional options &#8211; just use the normal command-line options without the hyphens. <\/p>\n<p>To use this options file, add the command-line option <em>&#8211;defaults-extra-file=${filename}<\/em>. A full example follows :-<\/p>\n<pre>\r\n$ mysql --defaults-extra-file=mysql-options-root.cnf --user=root --host=polio <<END\r\nheredoc> use misc;\r\nheredoc> select count(*) from films;\r\nheredoc> END\r\n<\/pre>\n<p>The output is not included (it&#8217;s none of your business how many films I&#8217;ve watched). And yes this does work for what I intended it to.<\/p>\n<p><em>As has been pointed out, it is also possible to schedule batch jobs within MySQL itself which may be a better answer in most cases.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Well, relatively safely anyway. The other day I felt the urge to knock up some SQL to clean up a MySQL table I&#8217;m responsible for. So I got the SQL prepared, but then needed to find out how to run this as a cron job (or batch file if you prefer). This was because I <a href='https:\/\/really.zonky.org\/?p=3404' class='excerpt-more'>[&#8230;]<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_share_on_mastodon":"0"},"categories":[4,226],"tags":[1225,1224,1201],"class_list":["post-3404","post","type-post","status-publish","format-standard","hentry","category-it","category-working-notes","tag-batch","tag-cronjob","tag-mysql","category-4-id","category-226-id","post-seq-1","post-parity-odd","meta-position-corners","fix"],"share_on_mastodon":{"url":"","error":""},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p1f2KI-SU","_links":{"self":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts\/3404","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3404"}],"version-history":[{"count":3,"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts\/3404\/revisions"}],"predecessor-version":[{"id":3407,"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts\/3404\/revisions\/3407"}],"wp:attachment":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}