<?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>DEV Community: Andy Lu</title>
    <description>The latest articles on DEV Community by Andy Lu (@_andy_lu_).</description>
    <link>https://dev.to/_andy_lu_</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%2F77174%2Fd9cd65ea-bed4-4997-b8cd-95e9fb7d69fb.jpg</url>
      <title>DEV Community: Andy Lu</title>
      <link>https://dev.to/_andy_lu_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_andy_lu_"/>
    <language>en</language>
    <item>
      <title>Python for Bash</title>
      <dc:creator>Andy Lu</dc:creator>
      <pubDate>Sun, 29 Jul 2018 02:15:37 +0000</pubDate>
      <link>https://dev.to/_andy_lu_/python-for-bash-3798</link>
      <guid>https://dev.to/_andy_lu_/python-for-bash-3798</guid>
      <description>&lt;p&gt;&lt;em&gt;This was originally published on my &lt;a href="https://andyrlu.com/2018/07/28/python-for-bash.html"&gt;blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Do you like &lt;code&gt;bash&lt;/code&gt; scripts? Personally, I don't.&lt;/p&gt;

&lt;p&gt;So when I need to write bash scripts, I figure out the commands I need, then &lt;br&gt;
glue them together with Python.&lt;/p&gt;

&lt;p&gt;It's been a while since I've needed to do this and while I neglected it before,&lt;br&gt;
the &lt;code&gt;subprocess&lt;/code&gt; module is the best way to run these commands. &lt;/p&gt;
&lt;h2&gt;
  
  
  A Quick Intro to Python's &lt;code&gt;subprocess.py&lt;/code&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Development Environment
&lt;/h3&gt;

&lt;p&gt;If you are following along with me here, you'll want to be using at least &lt;code&gt;python 3.5&lt;/code&gt;. Any version before that and you'll have to use a different API in this module to do the things I'll show you.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Command
&lt;/h3&gt;

&lt;p&gt;The workhorse of this module is the &lt;code&gt;subprocess.Popen&lt;/code&gt; class. There are a ton of arguments you can pass this class, but it can be overwhelming- and not to mention overkill- if you're new to this.&lt;/p&gt;

&lt;p&gt;Thankfully, there's a function in the &lt;code&gt;subprocess&lt;/code&gt; module that we can interface with instead: &lt;code&gt;subprocess.run()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's the function signature with some typical arguments passed in. (I pulled this from the &lt;a href="https://docs.python.org/3/library/subprocess.html"&gt;Docs&lt;/a&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None,
shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None,
text=None, env=None)*)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That looks pretty complicated, but we can actually ignore most of it and still do pretty neat things. Let's look at some examples.&lt;/p&gt;

&lt;h4&gt;
  
  
  A Basic Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import subprocess as sp

result = sp.run("pwd")
print(result)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/this/is/the/path/to/where/my/terminal/was/
CompletedProcess(args="pwd", returncode=0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output of this is the path to the directory you ran this script from; exactly what you would expect. Then there's some &lt;code&gt;CompletedProcess&lt;/code&gt; object. This is just an object that stores some information about the command that was run. For this guide, I'm ignoring it, but I'll have links at the end where you can read all about it.&lt;/p&gt;

&lt;p&gt;But that's it! That's all you need to run some basic &lt;code&gt;bash&lt;/code&gt; commands. The only caveat is you'll be lacking some features of a shell.&lt;/p&gt;

&lt;p&gt;To overcome this, let's look at the next example.&lt;/p&gt;

&lt;h4&gt;
  
  
  A Better Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import subprocess as sp

result = sp.run("ls -lah &amp;gt; someFile.txt", shell=True)
output = sp.run('ls -lah | grep ".txt"', shell=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may have noticed earlier in the function signature that &lt;code&gt;shell=False&lt;/code&gt;, but here I set it to &lt;code&gt;True&lt;/code&gt;. By doing so, the command I want actually gets run in a shell. That means I have access to redirection and pipes like I've shown.&lt;/p&gt;

&lt;p&gt;A note on running things like this: the command you want to execute must be typed exactly the way you would if you were doing it on a shell. If you read through the Documentation, you'll notice there is a way to run commands as by passing in a list of strings, where each string is either the command or a flag or input to the main command. &lt;/p&gt;

&lt;p&gt;I found this confusing because if you follow my "Better Example" way, you are never left wondering if you passed in the arguments correctly. On top of that, you are free to use Python to build up a command based on various conditions.&lt;/p&gt;

&lt;p&gt;Here's an example of me doing just that.&lt;/p&gt;

&lt;h4&gt;
  
  
  A "Real World" Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env python3

###############################################################################
#                                   Imports                                   #
###############################################################################
import subprocess as sp
from datetime import date

###############################################################################
#                                  Functions                                  #
###############################################################################

def getTodaysDate():
  currDate = date.today()
  return f"{currDate.year}-{currDate.month}-{currDate.day}"

def moveToPosts():
  lsprocess = sp.run("ls ./_drafts", shell=True)
  fileList = lsprocess.stdout.decode('utf-8').strip().split("\n")
  hasNewPost = len(fileList)

  if (hasNewPost == 1):
      print("New post detected")

      srcName = "./_drafts/" + fileList[0]
      destName = " ./_posts/" + getTodaysDate() + "-" + fileList[0]

      command = "mv "+ srcName + destName
      sp.run(command, shell=True)

      return [destName, files[0]]

  elif hasNewPost == 0:
      print("Write more!")
  else:
      print("Too many things, not sure what to do")

def runGit(fullPath, fileName):

  commitMsg = "'Add new blog post'"

  c1 = "git add " + fullPath
  c2 = "git commit -m " + commitMsg

  cmds = [c1,c2]

  for cmd in cmds:
    cp = sp.run(cmd, shell=True)

if __name__ == "__main__":
  pathToPost, fileName = moveToPosts()
  runGit(pathToPost, fileName)
  print("Done") 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since this blog is running thanks to Jekyll, I took advantage of the &lt;code&gt;_drafts&lt;/code&gt; folder available to me.&lt;/p&gt;

&lt;p&gt;For those of you unfamiliar with Jekyll, &lt;code&gt;_drafts&lt;/code&gt; is a folder where you can store blog posts that aren't ready to be published yet. Published posts go in &lt;code&gt;_posts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The filenames in this folder look like: &lt;code&gt;the-title-of-my-post.md&lt;/code&gt;. The filenames for published post that sit in the &lt;code&gt;_posts&lt;/code&gt; folder have the same name, but with the &lt;code&gt;year-month-day-&lt;/code&gt; attached to the front of the draft name.&lt;/p&gt;

&lt;p&gt;With this script, I just have to write a post and drop it into &lt;code&gt;_drafts&lt;/code&gt;. Then I open a terminal and run this script. First it looks in &lt;code&gt;_drafts&lt;/code&gt; and makes an array of the filenames it found. Anything other than just finding one file will stop the script- I'll improve this one day. With that file name and the help of &lt;code&gt;subprocess.run()&lt;/code&gt;, the script moves the draft into &lt;code&gt;_posts&lt;/code&gt;, gives it the appropriate name, then commits it to &lt;code&gt;git&lt;/code&gt; for me. &lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;I introduced the &lt;code&gt;subprocess.run()&lt;/code&gt; function, gave 3 examples of running &lt;code&gt;bash&lt;/code&gt; commands with it, and ended with the script that inspired this post in the first place. &lt;/p&gt;

&lt;p&gt;I personally don't have too many uses for &lt;code&gt;bash&lt;/code&gt; scripts. When I need one though, I'll definitely be writing it in Python and if it suits your needs, you should too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/subprocess.html"&gt;Python Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>terminal</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Explain Managing Projects Like I'm Five</title>
      <dc:creator>Andy Lu</dc:creator>
      <pubDate>Thu, 12 Jul 2018 19:59:50 +0000</pubDate>
      <link>https://dev.to/_andy_lu_/explain-managing-projects-like-im-five-4o7c</link>
      <guid>https://dev.to/_andy_lu_/explain-managing-projects-like-im-five-4o7c</guid>
      <description>&lt;p&gt;I was thinking about it today and I realized I don't know what the best practices are when it comes to managing projects. By that I mean, managing versions of Python for &lt;code&gt;Project A&lt;/code&gt; and &lt;code&gt;Project B&lt;/code&gt;; or whatever tool you use where versions may differ between projects.&lt;/p&gt;

&lt;p&gt;There's a 50% chance 'Managing Projects' is the wrong title for this ELI5. I'm just wondering what are the best ways to sandbox projects or if sandboxing projects is a good practice at all in the first place.&lt;/p&gt;

</description>
      <category>explainlikeimfive</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How do you keep up with all of your favorite blogs?</title>
      <dc:creator>Andy Lu</dc:creator>
      <pubDate>Sun, 24 Jun 2018 05:48:18 +0000</pubDate>
      <link>https://dev.to/_andy_lu_/how-do-you-keep-up-with-all-of-your-favorite-blogs-1gk2</link>
      <guid>https://dev.to/_andy_lu_/how-do-you-keep-up-with-all-of-your-favorite-blogs-1gk2</guid>
      <description>&lt;p&gt;Do you sign up for every mailing list you can? Use a RSS feed? Bookmark each blog and just visit them all? I'm curious to see everyone's strategy!&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
  </channel>
</rss>
