<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sirclesam</title>
    <description>The latest articles on Forem by Sirclesam (@sirclesam).</description>
    <link>https://forem.com/sirclesam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F155118%2F862fcb58-145f-40af-b723-dae6df4e9059.gif</url>
      <title>Forem: Sirclesam</title>
      <link>https://forem.com/sirclesam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sirclesam"/>
    <language>en</language>
    <item>
      <title>Send SMS with Chrome extension and AWS Lambda: Walkthrough</title>
      <dc:creator>Sirclesam</dc:creator>
      <pubDate>Tue, 24 Sep 2019 20:26:02 +0000</pubDate>
      <link>https://forem.com/sirclesam/sms-puppy-pics-to-ladyface-with-lambda-walkthrough-181m</link>
      <guid>https://forem.com/sirclesam/sms-puppy-pics-to-ladyface-with-lambda-walkthrough-181m</guid>
      <description>&lt;p&gt;I will browse through imgur when I have some time to kill, and often that means seeing pictures of things I know my ladyface will like, it's &lt;a href="https://i.imgur.com/W4lz9sP.mp4" rel="noopener noreferrer"&gt;usually puppies&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For a while I'd just right-click copy the URL, then open android SMS web app messages.google.com, find the lady, paste and DONE.  However, after a particularly cute day I found my self doing this several times in a row and it's not very efficient, so one lazy morning I got ambitious and got something cobbled together that worked...but wasn't ideal.&lt;/p&gt;

&lt;p&gt;My first version worked by sending the URL to my node server that's running &lt;a href="http://www.mapper.bike" rel="noopener noreferrer"&gt;one of my personal projects&lt;/a&gt; with some special query strings and using that to fire off an SMS using the Twilio module.  While this worked, it is less than ideal since it meant I have this code on my server that has nothing to do with its main purpose, but for something I cooked up in a few hours one morning, it will do.&lt;/p&gt;

&lt;p&gt;I finally got around to getting this to work the way I wanted, and that seems much more suited to the task, which is using AWS Lambda functions, and that's what I'm going to walk through here.&lt;/p&gt;

&lt;p&gt;I'll touch on the outline, then we'll step through the individual steps for getting it up and running.&lt;/p&gt;

&lt;p&gt;We'll be using a chrome extension to hit an AWS API Gateway, that's tied to a Lambda function that uses AWS SNS to send an SMS. Let's get started working backwards.&lt;/p&gt;

&lt;p&gt;Note: You'll need an AWS account with a credit card tied to it, everything I use is very cheap (0.00645 per SMS) but amazon still needs to be able to charge you.&lt;/p&gt;

&lt;h1&gt;
  
  
  SNS
&lt;/h1&gt;

&lt;p&gt;1) Go to &lt;a href="https://us-west-2.console.aws.amazon.com/sns/v3/home?region=us-west-2#/homepage" rel="noopener noreferrer"&gt;the SNS home page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F12rivn49rwq7g4xtqqjn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F12rivn49rwq7g4xtqqjn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) create a new topic, named anything you like.&lt;/p&gt;

&lt;p&gt;3) Give your topic a display name.  Note the first 10 characters of this will show up on every SMS you send. So for mine being PupperSMS texts look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PupperSMS&amp;gt;http://i.imgur.com/cRF0KoB.jpg&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;4) Create an SMS subscription for this topic.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click create subscription, select the ARN for the topic you just created.&lt;/li&gt;
&lt;li&gt;Put the phone number you intend to send things to in the endpoint, I use the full +11234567890 style&lt;/li&gt;
&lt;li&gt;I advise using your number at first so your intended audience doesn't have to get your test messages.&lt;/li&gt;
&lt;li&gt;You can include multiple subscriptions here if you want to send to multiple numbers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;5) Test it.&lt;br&gt;&lt;br&gt;
You can test that it works by clicking 'Publish Message' enter something in the body and click 'Publish Message' at the bottom.  You should get an SMS from a 5 digit number at the number you put in with your display name at the beginning.&lt;/p&gt;

&lt;p&gt;6) Keep track of the ARN, we'll need that for later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fg5k8hfrna1jyq2wkmvt1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fg5k8hfrna1jyq2wkmvt1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Lambda
&lt;/h1&gt;

&lt;p&gt;Now for the fun stuff.&lt;/p&gt;

&lt;p&gt;1) Go to &lt;a href="https://us-west-2.console.aws.amazon.com/lambda/home?region=us-west-2#/begin" rel="noopener noreferrer"&gt;the AWS lambda homepage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) Click 'create a function', choose 'author from scratch' and runtime as 'python 2.7'&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it will take a bit, AWS also creates an IAM role for your lambda func&lt;/li&gt;
&lt;li&gt;Note: I had errors with the default role creation, so I used one I created in IAM.  &lt;a href="https://console.aws.amazon.com/iam/home?#/roles" rel="noopener noreferrer"&gt;You can create one here&lt;/a&gt;
choose lambda for services and AdministratorAccess for permissions.  It's probably overkill for what we're doing but will work for now.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3) Add in the lambda python code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from __future__ import print_function

import json
import urllib
import boto3
import os

print('Loading message function...')

def lambda_handler(event, context):
    if event["queryStringParameters"]["key"] == os.environ["KEY"]:
        send_to_sns(event["queryStringParameters"]["url"], context)
        message = "Message Sent!"
    else:
        message = "Invalid Key - try again"
    return {
        "statusCode": 200,
        "body": json.dumps(message)
    }

def send_to_sns(smsMessage,context):
    sns = boto3.client('sns')
    sns.publish(
        TopicArn={YOUR SNS ARN HERE},
        Message=smsMessage
    )

    return ('Sent a message to an Amazon SNS topic.')

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before this will work you need to grab the ARN from your SNS and set it to the TopicArn above.  Like this:&lt;br&gt;
&lt;code&gt;TopicArn="arn:aws:sns:us-west-2:1234567890:mySMS",&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can test this by changing the lambda handler to lambda_function.send_to_sns and a test event to just a string.  Once you hit test, it should send an SMS with that string to your phone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3xn479322oe9xpaf9h29.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3xn479322oe9xpaf9h29.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change the handler back to lambda_function.lambda_handler and I'll briefly go over what's going on in the other function.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Frul8w5ut0oysztsyi3he.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Frul8w5ut0oysztsyi3he.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We're going to use AWS API gateway to activate this function, which will give us a URL we can hit, and using something called Lambda Proxy which will allow us to take query strings from a URL and pass them to the lambda function in the event object. &lt;/p&gt;

&lt;p&gt;These are stored in the 'queryStringParameters' object. The 'url' is the data we're interested in, but you'll notice there's also a 'key' parameter.  This is to add a bit of security to our api so that not anyone in the world can trigger this, but only when the api is hit with the correct key value. &lt;/p&gt;

&lt;p&gt;This can probably be done with AWS security features, but I haven't gotten that far yet - if you have a better method please let me know!&lt;/p&gt;

&lt;p&gt;Pick something that you'll use as your security key.  I use a UUID string, you can generate one here: &lt;a href="https://www.uuidgenerator.net/" rel="noopener noreferrer"&gt;https://www.uuidgenerator.net/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right under the code on your lambda function, there's a section for environment variables - place your KEY / UUID here.  It doesn't need to be long, but it should be long enough that brute force is out of the question. You could even correct horse battery staple it: &lt;a href="https://www.xkcd.com/936/" rel="noopener noreferrer"&gt;https://www.xkcd.com/936/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fn35rqy4oh1b09jis8fcm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fn35rqy4oh1b09jis8fcm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  API Gateway
&lt;/h1&gt;

&lt;p&gt;Time to expose our lambda to the world!&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://us-west-2.console.aws.amazon.com/apigateway/home?region=us-west-2#/welcome" rel="noopener noreferrer"&gt;Go to API Gateway portal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) Click 'get started' to create a new API&lt;/p&gt;

&lt;p&gt;3)Select New API, give it a name and description, leave endpoint as regional, click 'create API'&lt;/p&gt;

&lt;p&gt;4) Click 'actions' --&amp;gt; 'create method', select GET from the dropdown and click the checkmark.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcjbkw94aeq6ga3jxorgj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcjbkw94aeq6ga3jxorgj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5) Select integration type: Lambda Function&lt;/p&gt;

&lt;p&gt;6) Check 'use lambda proxy integration'&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5eh5ys499tzkp0ru7p1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5eh5ys499tzkp0ru7p1v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7) select your lambda function by name in the lambda function field.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select ok to allow the API access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;8) We'll need to enable query strings so we can pass data to our api and our lambda function.  Click method request&lt;/p&gt;

&lt;p&gt;8) Test your API by clicking the Test with the lightning icon.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter url=canYouHearMeNow&amp;amp;key=YOURKEY in the query string field and hit test&lt;/li&gt;
&lt;li&gt;You should see 'message sent' and get a sms on your phone!&lt;/li&gt;
&lt;li&gt;Almost there, home stretch!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ff1n0iu7k4llcv5q5nggu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ff1n0iu7k4llcv5q5nggu.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;9)Deploy your API.  Click 'actions' and select deploy API&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new stage name&lt;/li&gt;
&lt;li&gt;TADA! you now have a url you can hit to trigger your lambda function.&lt;/li&gt;
&lt;li&gt;Remember you'll need the query string ?url=YOURURL&amp;amp;key=YOURKEY at the end of it to work as expected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fi6eheb1xvc7qfti3o182.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fi6eheb1xvc7qfti3o182.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Chrome Extention
&lt;/h1&gt;

&lt;p&gt;This will be pretty simple, only 2 files.  However, it does involve putting your chrome extension in developer mode which does have some security implications, so be warned.    &lt;/p&gt;

&lt;p&gt;1) Download the repo at &lt;a href="https://github.com/sselfridge/send-it" rel="noopener noreferrer"&gt;https://github.com/sselfridge/send-it&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zip here: &lt;a href="https://github.com/sselfridge/send-it/archive/master.zip" rel="noopener noreferrer"&gt;https://github.com/sselfridge/send-it/archive/master.zip&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2) Put the unzipped files somewhere they can live going forward, they will be executed from here.&lt;/p&gt;

&lt;p&gt;3) You only need to edit script.js, but you can modify manifest.json if you'd like to name it something else besides 'send it!'&lt;/p&gt;

&lt;p&gt;4) In script.js add in your key and AWS endpoint&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const AWS_API_ENPOINT = "https://123456789.execute-api.us-west-2.amazonaws.com/PuppyStage";
  const KEY = "correcthorsebatterystaple";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Open Chrome and go to the 'manage extensions' page.  You can get to it by right-clicking on any extension icons you have and click 'manage extensions' there.&lt;/p&gt;

&lt;p&gt;6) click the 'developer mode' toggle in the top right&lt;/p&gt;

&lt;p&gt;7) click 'load unpacked' in the new menu on the top left&lt;/p&gt;

&lt;p&gt;8) select your folder&lt;/p&gt;

&lt;p&gt;You're done! Go to any image in chrome and right-click on it, you should see the 'send it' option there and clicking it will send that URL to your number.&lt;/p&gt;

&lt;p&gt;Remember you'll have to change/add more subscriptions in the AWS SNS console depending on which numbers you want to send it to.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Further Work
&lt;/h1&gt;

&lt;p&gt;This does leave some things to be desired.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There's no feedback if things stop working at any point.&lt;/li&gt;
&lt;li&gt;No icons for chrome extension&lt;/li&gt;
&lt;li&gt;Chrome warnings about dev mode on startup. Could be fixed by publishing to the chrome store, which I've done personally, but the AWS API endpoint is hardcoded since I didn't add the UI elements to prompt for it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cheers and happy puppy-ing!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>sms</category>
      <category>lambda</category>
      <category>chrome</category>
    </item>
    <item>
      <title>Fun with BASH Pt: 2 Aliases</title>
      <dc:creator>Sirclesam</dc:creator>
      <pubDate>Mon, 03 Jun 2019 14:00:14 +0000</pubDate>
      <link>https://forem.com/sirclesam/fun-with-bash-pt-2-aliases-2imj</link>
      <guid>https://forem.com/sirclesam/fun-with-bash-pt-2-aliases-2imj</guid>
      <description>&lt;p&gt;Pt 1: &lt;a href="https://dev.to/sirclesam/fun-with-bash-pt-1-scripting-51l9"&gt;https://dev.to/sirclesam/fun-with-bash-pt-1-scripting-51l9&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one will be short, which makes sense in context.&lt;/p&gt;

&lt;p&gt;Another way to save precious keystroked when working in the terminal is to use bash aliases.  My main use for this is to get to project directories that I access frequently.  &lt;/p&gt;

&lt;p&gt;If you read my previous post about writing bash scripts you may have thought to try something like this, but realized after the script executes that you're still in the same directory.  This is because in .sh scripts cd just changes the directory in the context of the script and not your active shell, luckily alias can help with this.&lt;/p&gt;

&lt;p&gt;Once again we're going to be editing our bash profile file in our home dir.  For most BASH shells on linux this will be ~/.bashrc however because apple with the stock OSX terminal it is ~/.bash_profile.&lt;/p&gt;

&lt;p&gt;For a while, I've been doing daily hack-hours to practice algorithm solving, pulling from a daily updated repo that has new problems in it every day.  In order to interact with the scripts I need to be in their directory which means typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd hack-hour/challenges/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;which even with tab correction still equals 5 keystrokes every morning.  Ain't nobody got time for that!&lt;/p&gt;

&lt;p&gt;open up your bash profile and insert the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias hh="cd ~/hack-hour/challenges"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go open a new terminal (has to be new, remember the profile settings get added when a terminal is opened) and try it! &lt;/p&gt;

&lt;p&gt;TAH DAH!!&lt;/p&gt;

&lt;p&gt;Originally that was going to be all for this article, but I learned a new BASH trick that I can rope back into this so you get that too.&lt;/p&gt;

&lt;p&gt;I just learned you can &lt;code&gt;cd -&lt;/code&gt; to go back the previous directory you were in, pretty neat but got me thinking about some alias work I'd done in college when we lived in the terminal.&lt;/p&gt;

&lt;p&gt;pushd is a less well-known sibling of cd.  It does the same thing but as its name might have suggested it does a push, and this is on to a directory stack.  The benefit of this is you can do a popd to traverse backwards through the stack.&lt;/p&gt;

&lt;p&gt;Another thing to note about aliases, that this demonstrates, is they get executed before anything on your PATH environment variable, so if you add this to your profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias cd="pushd"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;now anytime cd is used it will call pushd instead and you can utilize popd to go back in your directory history, if &lt;code&gt;cd -&lt;/code&gt; doesn't get the job done!&lt;/p&gt;

&lt;p&gt;That's it for now, &lt;br&gt;
cheers&lt;/p&gt;

</description>
      <category>bash</category>
      <category>terminal</category>
      <category>shortcut</category>
      <category>lyfehack</category>
    </item>
    <item>
      <title>Fun with BASH Pt:1 Scripting</title>
      <dc:creator>Sirclesam</dc:creator>
      <pubDate>Thu, 11 Apr 2019 04:11:38 +0000</pubDate>
      <link>https://forem.com/sirclesam/fun-with-bash-pt-1-scripting-51l9</link>
      <guid>https://forem.com/sirclesam/fun-with-bash-pt-1-scripting-51l9</guid>
      <description>&lt;h1&gt; Fun with BASH &lt;/h1&gt;

&lt;h3&gt; Part 1: Scripting &lt;/h3&gt;

&lt;p&gt;Ever find yourself typing out the same long command line groups over and over?&lt;/p&gt;

&lt;p&gt;BASH scripting can help!&lt;/p&gt;

&lt;p&gt;Let's say you want to want to commit and push to your git repo in one command instead of doing it separately.  &lt;/p&gt;

&lt;p&gt;(Note on code examples: &amp;gt;$ will be used to indicate the terminal and --&amp;gt; the output from entering that command)&lt;/p&gt;

&lt;p&gt;Let's get started:&lt;br&gt;
Open your terminal - we're going to be working your root directory. Create a new file.  the .sh extension is usually used on BASH scripts&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;gt;$ touch commitpush.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Before we edit the script we're going to need to make this file executable. Because right now if we try to execute it we get an error.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;gt;$ ./commitpush.sh --&amp;gt; bash: ./commitpush.sh: Permission denied&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To do this we use the chmod command which stands for change-mode.  We're going to call it on our script with the flag a+x.  This will make this file executable for all users.  see the man page for chomod for other options.  If you want to remove executability use the flag a-x&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;gt;$ chmod a+x commitpush.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;One last thing before we can start on the script, we need to find out where BASH is on your computer so we can tell the script where to look to execute itself.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;gt;$ whereis bash --&amp;gt;  /bin/bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note my OSX system has bash in the root bin/ folder but yours might be different.&lt;/p&gt;

&lt;p&gt;Time to start editing the script file!&lt;/p&gt;

&lt;p&gt;First is to use that info we got from whereis to tell the script where to look to execute itself.  This is done with the #! character.  Adding the following to your file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!{yourBASHPATH}
echo This is Working!!!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can execute this script&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;gt;$ ./commitpush.sh  ---&amp;gt; This is Working!!!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Nice but doesn't help us with much, let's change it to actually have some functionality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
git commit -a
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note using the -a flag on git commit will only commit changes to files that have already being tracked by git, you'll still need to git add any new files.&lt;/p&gt;

&lt;p&gt;Well now have a script to save us typing two lines every time, but it's not easy to call it.  You're probably used to running bash commands by just typing their name, but if you've noticed every time we've run this script we've prefaced it with ./&lt;/p&gt;

&lt;p&gt;This is because as a security measure BASH won't let you execute just any file by name, even if you're in the directory.   &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;gt;$ commitpush.sh  --&amp;gt;  -bash: commitpush.sh: command not found&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There's another inconvenience issue as well - while a bash script executes in whatever the current directory is, you will still have to reference its current location to execute it. If you're several layers deep this can be irritating. &lt;/p&gt;

&lt;p&gt;Let's say your git project is located in ~/codesmith/gitRepos/myProject/ in order to run the script in your home directory you'd have to enter:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;../../../commitpush.sh&lt;/code&gt;   &lt;/p&gt;

&lt;p&gt;Luckily there's a built-in system we can use, the $PATH environment variable.  You can see your using the echo command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;gt;$ echo $PATH  --&amp;gt;  /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Each of these directories is where BASH will look in order to execute a command.  So one thing we can do is put our script in one of these directories.  I recommend the /usr/local/bin since its less likely to interfer with any built in system commands.&lt;/p&gt;

&lt;p&gt;We can move it in using the move (mv) command.   &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;gt;$ cd&lt;/code&gt; -Gets us back to the home directory&lt;br&gt;
&lt;code&gt;&amp;gt;$ sudo mv commitpush.sh /usr/local/bin&lt;/code&gt; - moves script to the local bin.  &lt;/p&gt;

&lt;p&gt;The directory we're putting it in is protected so you'll need to use &lt;code&gt;sudo&lt;/code&gt; and enter your password to get it.&lt;/p&gt;

&lt;p&gt;Now you can just type commitpush.sh from any directory where you have an active git repo and it will take care of the rest!&lt;/p&gt;

&lt;p&gt;One thing to note is using this method means your commit message will open in vi.  Get into 'INSERT' mode by hitting the i key then type your message.  Exit and save in vi by hitting '[Esc] : w q [enter]'&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F43w4m4sqosam3zqvt1dv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F43w4m4sqosam3zqvt1dv.png" alt="The key to quitting vi"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don't like this, then read on and I'll cover how to do this without messing with vi.&lt;/p&gt;

&lt;h3&gt; Pt 2 - Checking for errors and varibles &lt;/h3&gt;

&lt;p&gt;So this works in the ideal case, but what if there are errors with your commit? We don't want to push when there is something wrong so this should have some logic keep that from happening.  We can do this in our script with exit codes and some conditionals.&lt;/p&gt;

&lt;h4&gt;Exit codes&lt;/h4&gt;

&lt;p&gt;Every command that runs in BASH is supposed to return an exit code.  This is 0 if everything went as expected and not 0 in the case of anything else.  Usually, it's 1 but non-zero is the important part.&lt;/p&gt;

&lt;p&gt;This is stored in the BASH varible $? and you can see it by using the echo command.&lt;/p&gt;

&lt;p&gt;Success example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;$ cp cp.sh commitpushCOPY.sh
&amp;gt;$ echo $? ----&amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Failure example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;$ cp MADEUPFILE.sh commitpushCOPY.sh  ---&amp;gt; No such file or directory
&amp;gt;$ echo $? ----&amp;gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something that can be tricky here is that 'echo $?' its self is a command so it will set the exit code when it runs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;$ cp MADEUPFILE.sh commitpushCOPY.sh  ---&amp;gt; No such file or directory
&amp;gt;$ echo $? ----&amp;gt; 1
&amp;gt;$ echo $? ----&amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to put it in our script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
git commit -a 

if [ $? = 0 ] 
then
  git push
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the how instead of curley braces this uses fi to end the block.  Let's add some output to make this more user friendly and to show how the if then/else works in scripting. The comparison is done with a single = operator not the usual === you've been used to in JS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
git commit -a 

if [ $? = 0 ] 
then
  echo 'Commit success, pushing'
  git push
else
  echo 'Commit failure, aborting push'
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now at least it will be a little more robust and not push anything when we don't expect it to.&lt;/p&gt;

&lt;p&gt;But there's still one annoying thing this script does and that's forcing us to enter our commit message in vi and then try to remember how to write-quit vi.&lt;/p&gt;

&lt;p&gt;The final entry here will be how to avoid that using parameters.&lt;/p&gt;

&lt;p&gt;You're already used to using these.  Anything that comes after the command you're using is a parameter.  This is commonly flags -a  --save or file names that the program needs to use.&lt;/p&gt;

&lt;p&gt;using them in a bash script is pretty straight forward.  Each space separated value will come in as a bash variable with a number following it.&lt;/p&gt;

&lt;p&gt;Script foo.sh&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin.bash

echo $1
echo 'Line of text'
echo $2
echo 'More text'
echo $3
echo 'and even more text'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the above script we get&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;$ ./foo.sh bar baz
bar
Line of text
baz
More text

and even more text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See how bar and baz are listed and there's an empty line since there is no $3 argument provided.&lt;/p&gt;

&lt;p&gt;So using this and the -m flag with git commit we can avoid vi.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
git commit -a -m $1

if [ $? = 0 ] 
then
  echo 'Commit success, pushing'
  git push
else
  echo 'Commit failure, aborting push'
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can commit and push your change with one line!&lt;/p&gt;

&lt;p&gt;`&amp;gt;$ commitpush.sh 'Commit and push progress on the current branch'&lt;/p&gt;

&lt;p&gt;You'll have to put quotes around your message otherwise your commit message will just be one word.&lt;/p&gt;

&lt;p&gt;If you want to avoid this - add in error checking that will abort the entire script if more than one parameter is provided.&lt;/p&gt;

&lt;p&gt;Happy coding!!!&lt;/p&gt;

&lt;p&gt;Pt 2: Aliases&lt;br&gt;
&lt;a href="https://dev.to/sirclesam/fun-with-bash-pt-2-aliases-2imj"&gt;https://dev.to/sirclesam/fun-with-bash-pt-2-aliases-2imj&lt;/a&gt;&lt;/p&gt;

</description>
      <category>bash</category>
      <category>shortcuts</category>
      <category>lyfehax</category>
    </item>
  </channel>
</rss>
