<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:series="http://unfoldingneurons.com/"
><channel><title>David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞. &#187; Shell</title> <atom:link href="http://davidwalsh.name/tutorials/shell/feed" rel="self" type="application/rss+xml" /><link>http://davidwalsh.name</link> <description>Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</description> <lastBuildDate>Sun, 20 May 2012 22:40:48 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.2</generator> <item><title>Squash Commits with&#160;Git</title><link>http://davidwalsh.name/squash-commits-git</link> <comments>http://davidwalsh.name/squash-commits-git#comments</comments> <pubDate>Sun, 29 Apr 2012 03:52:17 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Shell]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5422</guid> <description><![CDATA[I&#8217;m not a git expert but I know enough git to get by, and surely know enough git to appreciate its ease of use over svn. A while ago I published some basic git commands to that go slightly beyond basic cloning and commits, and should handle most git interactions. Today&#8217;s mini git lesson involves [...]<p><a
href="http://davidwalsh.name/squash-commits-git">Squash Commits with&nbsp;Git</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>I&#8217;m not a git expert but I know enough git to get by, and surely know enough git to appreciate its ease of use over svn.  A while ago I published some <a
href="http://davidwalsh.name/git-commands">basic git commands</a> to that go slightly beyond basic cloning and commits, and should handle most git interactions.  Today&#8217;s mini git lesson involves squashing multiple commits into one, allowing for easier pull request review and merge management.</p><p>Start by making changes to the feature branch you&#8217;re doing work on.  Let&#8217;s assume that these changes span a few commits and I want to consolidate them into one commit.  The first step involves making sure the master branch is up to date with the destination repo&#8217;s master branch:</p><pre class="shell">
# switch to master branch
git checkout master

# ensure our master is up to date
git pull remoteRepoName master
</pre><p>With the master branch up to date, we&#8217;ll use git rebase to consolidate:</p><pre class="shell">
git rebase -i master
</pre><p>That command will show a list of each commit, as such:</p><pre class="shell">
pick fb554f5 This is commit 1
pick 2bd1903 This is commit 2
pick d987ebf This is commit 3

# Rebase 9cbc329..d987ebf onto 9cbc329
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
</pre><p>Edit the summary shown to you by the rebase command, leaving the commit you want to be the main commit as &#8220;pick&#8221; and changing all subsequent &#8220;pick&#8221; commands as &#8220;squash&#8221;:</p><pre class="shell">
pick fb554f5 This is commit 1
squash 2bd1903 This is commit 2
squash d987ebf This is commit 3

# Rebase 9cbc329..d987ebf onto 9cbc329
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
</pre><p>Write/quit past the editor twice (the second screen would allow you to change the commit message, though I like to keep it the same).  At this point, your commits are squashed into one.  Run the following command to force a push of the new, consolidated commit:</p><pre class="shell">
git push -f
</pre><p>This forced push updates the source repository and our commits have become one.  If you had already submitted a pull request at GitHub, the pull request would now show only one commit!  With one consolidated commit, code review becomes much, much easier!</p><p><a
href="http://davidwalsh.name/squash-commits-git">Squash Commits with&nbsp;Git</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/squash-commits-git/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>OSX Lion Dock&#160;Dividers</title><link>http://davidwalsh.name/osx-lion-dock-dividers</link> <comments>http://davidwalsh.name/osx-lion-dock-dividers#comments</comments> <pubDate>Fri, 20 Apr 2012 22:37:09 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Shell]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5418</guid> <description><![CDATA[One thing I hate is Tottenham Football Club clutter.  I hate cluttered code, files littered on the desktop, and keeping files in my Downloads folder that I&#8217;ll never need again.  One place I especially hate clutter is my OSX application dock.  I recently upgraded to OSX Lion and found that my old divider apps, which I [...]<p><a
href="http://davidwalsh.name/osx-lion-dock-dividers">OSX Lion Dock&nbsp;Dividers</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>One thing I hate is <del>Tottenham Football Club</del> clutter.  I hate cluttered code, files littered on the desktop, and keeping files in my Downloads folder that I&#8217;ll never need again.  One place I <em>especially</em> hate clutter is my OSX application dock.  I recently upgraded to OSX Lion and found that my old divider apps, which I used to separate related dock apps, were no longer acceptable.  As you can imagine, I wasn&#8217;t impressed.  Luckily I found a great way to create dividers on <em>both</em> sides of the dock with minimal fuss and without the need for phantom apps!</p><h2>Step 1:  Create the&nbsp;Dividers</h2><p>Open the Terminal and execute the first command to create a divider on the left or the second comment to add one on the right:</p><pre class="shell">
# Left side
defaults write com.apple.dock persistent-apps -array-add '{tile-data={}; tile-type="spacer-tile";}'

# Right Side
defaults write com.apple.dock persistent-others -array-add '{tile-data={}; tile-type="spacer-tile";}'
</pre><p>Execute the command as many times as you like; a divider will be created each time.  You will not, however, see them added before your eyes.</p><h2>Step 2:  Reset the&nbsp;Dock</h2><p>Reset the dock to see your new divider(s):</p><pre class="shell">
# Reset the dock
killall Dock
</pre><p>Once the dock is reset, you&#8217;ll see spacers which you&#8217;ll be able to drag throughout the dock.</p><p>Why dividers aren&#8217;t a common feature of OSX yet is a question I can&#8217;t answer.  Luckily we can abuse Terminal to make our dividers though.</p><p><a
href="http://davidwalsh.name/osx-lion-dock-dividers">OSX Lion Dock&nbsp;Dividers</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/osx-lion-dock-dividers/feed</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Useful Git&#160;Commands</title><link>http://davidwalsh.name/git-commands</link> <comments>http://davidwalsh.name/git-commands#comments</comments> <pubDate>Wed, 15 Feb 2012 17:14:29 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Shell]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5387</guid> <description><![CDATA[I&#8217;ve used git quite a bit but I don&#8217;t consider myself a git expert, per se. I often find myself looking up the same basic commands so I thought I&#8217;d share them there so I&#8217;d have a fast reference, and maybe this will help you out too! Create and Checkout a New&#160;Branch #branches from currently [...]<p><a
href="http://davidwalsh.name/git-commands">Useful Git&nbsp;Commands</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>I&#8217;ve used git quite a bit but I don&#8217;t consider myself a git expert, per se.  I often find myself looking up the same basic commands so I thought I&#8217;d share them there so I&#8217;d have a fast reference, and maybe this will help you out too!</p><h3>Create and Checkout a New&nbsp;Branch</h3><pre class="shell">
#branches from currently checked out directory
git checkout -b &lt;branchName&gt;
</pre><h3>Checkout a Remote&nbsp;Branch</h3><pre class="shell">
git checkout -b &lt;localBranchName&gt; origin/&lt;remoteBranchName&gt;
</pre><h3>Abort Changes of a&nbsp;File</h3><pre class="shell">
git checkout -- &lt;fileName&gt;
</pre><h3>Modify the Previous Commit&#8217;s&nbsp;Message</h3><pre class="shell">
git commit --amend
</pre><h3>Partial Change&nbsp;Checkin</h3><pre class="shell">
git add --edit
</pre><h3>Undo the Previous&nbsp;Commit</h3><pre class="shell">
git revert HEAD^
</pre><h3>Temporarily Stash Changes, Restore&nbsp;Later</h3><pre class="shell">
# After changes have been made...
git stash

# Do some other stuff here, like switch branches, merge other changes, etc.

#Re-apply the changes
git stash pop
</pre><h3>Delete a Remote&nbsp;Branch</h3><pre class="shell">
git push origin :&lt;branchName&gt;
</pre><h3>Pull in the Latest from a Shared&nbsp;Repository</h3><pre class="shell">
# Add a remote branch
git remote add &lt;remoteName&gt; &lt;gitAddress&gt;
	# For example:  git remote add lightfaceOfficial git://github.com/darkwing/LightFace.git

# Get changes from that branch
git fetch &lt;remoteName&gt;
</pre><h3>Tagging, Deleting, and Pushing&nbsp;Tags</h3><pre class="shell">
# Create a Tag
git tag &lt;tagName&gt;

# Delete the tag
git tag -d &lt;tagName&gt;

# Push Tags
git push --tags
</pre><h3>Who F&#8217;d it All&nbsp;Up?</h3><pre class="shell">
git blame &lt;fileName&gt;
</pre><p>These basic git commands should help you on your way.  Have a tip you&#8217;d like to share with others?  Please share!</p><p><a
href="http://davidwalsh.name/git-commands">Useful Git&nbsp;Commands</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/git-commands/feed</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Recursively Delete .svn&#160;Directories</title><link>http://davidwalsh.name/delete-svn</link> <comments>http://davidwalsh.name/delete-svn#comments</comments> <pubDate>Thu, 17 Mar 2011 14:01:25 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Shell]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5188</guid> <description><![CDATA[Version control systems are hugely important when it comes to development of all kinds.  I&#8217;m a huge fan of git but sometimes I&#8217;m required to use SVN.  Unfortunately I tend to forget to remove .svn folders when I copy and paste from a directory structure template.  This, of course, leads to me overwriting files and [...]<p><a
href="http://davidwalsh.name/delete-svn">Recursively Delete .svn&nbsp;Directories</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>Version control systems are hugely important when it comes to development of all kinds.  I&#8217;m a huge fan of git but sometimes I&#8217;m required to use SVN.  Unfortunately I tend to forget to remove .svn folders when I copy and paste from a directory structure template.  This, of course, leads to me overwriting files and results in mass confusion.  I recently <a
href="http://www.crainbandy.com/linux/recursively-remove-svn-directories-2">stumbled up</a> an awesome command line script which recursively removes .svn directories from parent directories.</p><pre class="shell">
find . -type d -name .svn -exec rm -rf {} \;
</pre><p>The script starts within the current directory, so be sure you navigate to the directory you want to start searching from first. This script would work on any search type; simply replace &#8220;.svn&#8221; with the search of your choosing but be careful:  if your search term is too general, you may end up deleting a bunch of stuff you don&#8217;t want to!</p><p><a
href="http://davidwalsh.name/delete-svn">Recursively Delete .svn&nbsp;Directories</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/delete-svn/feed</wfw:commentRss> <slash:comments>19</slash:comments> </item> <item><title>Fixing Python&#8217;s &#8220;Python Eggs&#8221;&#160;Error</title><link>http://davidwalsh.name/python-eggs</link> <comments>http://davidwalsh.name/python-eggs#comments</comments> <pubDate>Thu, 25 Feb 2010 14:29:00 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Shell]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=4879</guid> <description><![CDATA[Let me first state this for the record: I am not a server guy. The closest I&#8217;ve ever gotten to compiling my own versions of code is &#8220;sudo port install &#8230;&#8221; So when I decided to teach myself Python (creating simply database interaction, record listings, etc) and kept getting &#8220;500 Internal Server Error&#8221; messages, I [...]<p><a
href="http://davidwalsh.name/python-eggs">Fixing Python&#8217;s &#8220;Python Eggs&#8221;&nbsp;Error</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>Let me first state this for the record:  I am not a server guy.  The closest I&#8217;ve ever gotten to compiling my own versions of code is &#8220;sudo port install &#8230;&#8221;  So when I decided to teach myself Python (creating simply database interaction, record listings, etc) and kept getting &#8220;500 Internal Server Error&#8221; messages, I thought I was doomed.  I opened up the Apache error log and saw this:</p><pre class="shell">
[error] [client ::1] Traceback (most recent call last):
[error] [client ::1]   File &quot;/Users/davidwalsh83/Projects/server/something.py&quot;, line 6, in &lt;module&gt;
[error] [client ::1]     import MySQLdb, cgi, cgitb, httplib, urllib2
[error] [client ::1]   File &quot;build/bdist.macosx-10.6-universal/egg/MySQLdb/__init__.py&quot;, line 19, in &lt;module&gt;
[error] [client ::1]   File &quot;build/bdist.macosx-10.6-universal/egg/_mysql.py&quot;, line 7, in &lt;module&gt;
[error] [client ::1]   File &quot;build/bdist.macosx-10.6-universal/egg/_mysql.py&quot;, line 4, in __bootstrap__
[error] [client ::1]   File &quot;/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py&quot;, line 835, in resource_filename
[error] [client ::1]     self, resource_name
[error] [client ::1]   File &quot;/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py&quot;, line 1304, in get_resource_filename
[error] [client ::1]     self._extract_resource(manager, self._eager_to_zip(name))
[error] [client ::1]   File &quot;/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py&quot;, line 1326, in _extract_resource
[error] [client ::1]     self.egg_name, self._parts(zip_path)
[error] [client ::1]   File &quot;/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py&quot;, line 915, in get_cache_path
[error] [client ::1]     self.extraction_error()
[error] [client ::1]   File &quot;/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py&quot;, line 881, in extraction_error
[error] [client ::1]     raise err
[error] [client ::1] pkg_resources.ExtractionError: Can't extract file(s) to egg cache
[error] [client ::1] 
[error] [client ::1] The following error occurred while trying to extract file(s) to the Python egg
[error] [client ::1] cache:
[error] [client ::1] 
[error] [client ::1]   [Errno 20] Not a directory: '/Library/WebServer/.python-eggs/MySQL_python-1.2.3c1-py2.6-macosx-10.6-universal.egg-tmp'
[error] [client ::1] 
[error] [client ::1] The Python egg cache directory is currently set to:
[error] [client ::1] 
[error] [client ::1]   /Library/WebServer/.python-eggs
[error] [client ::1] 
[error] [client ::1] Perhaps your account does not have write access to this directory?  You can
[error] [client ::1] change the cache directory by setting the PYTHON_EGG_CACHE environment
[error] [client ::1] variable to point to an accessible directory.
[error] [client ::1] 
[error] [client ::1] Premature end of script headers: something.py
</pre><p>My first thought was &#8220;Wow, that&#8217;s quite a long way of telling me to &#8216;just quit.&#8217;&#8221;  Not wanting to concede defeat, I did some quick Google searching to find that the following snippet of Python code would allow me program another day:</p><pre class="shell">
import os
os.environ['PYTHON_EGG_CACHE'] = '/tmp'
</pre><p>I&#8217;d like to pretend I know what that means but I really don&#8217;t know.  In any event, if you start receiving those errors, this snippet could be your ticket to taking a bite out of Python.</p><p><a
href="http://davidwalsh.name/python-eggs">Fixing Python&#8217;s &#8220;Python Eggs&#8221;&nbsp;Error</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/python-eggs/feed</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>MooTools Forge / GitHub Plugin Structure Shell&#160;Script</title><link>http://davidwalsh.name/mootools-forge-script</link> <comments>http://davidwalsh.name/mootools-forge-script#comments</comments> <pubDate>Tue, 15 Dec 2009 14:11:47 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[MooTools]]></category> <category><![CDATA[Shell]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=4410</guid> <description><![CDATA[One thing I love about the MooTools Forge is that it requires a strict structure for its plugins i.e. requiring a README.md file, Source directory, etc. I&#8217;ve created a shell script that I can run that creates the directory structure and files required to add my plugin to GitHub and then the Forge. The Shell [...]<p><a
href="http://davidwalsh.name/mootools-forge-script">MooTools Forge / GitHub Plugin Structure Shell&nbsp;Script</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>One thing I love about the MooTools Forge is that it requires a strict structure for its plugins i.e. requiring a README.md file, Source directory, etc.  I&#8217;ve created a shell script that I can run that creates the directory structure and files required to add my plugin to GitHub and then the Forge.</p><h2>The Shell Script &amp; Usage</h2><p>The first step is creating the repository at GitHub.  Once created at GitHub, I run the script, giving it the name of the plugin and repository (they must be the same):</p><pre class="shell">
./newPlugin.sh ScrollSpy
</pre><p>The script itself looks like:</p><pre class="shell">
#!/bin/sh
mkdir $1
cd $1
git init
touch README.md
mkdir Source
touch Source/$1.js
touch Source/$1-yui-compressed.js
mkdir Docs
touch Docs/$1.md
touch package.yml
echo &quot;name:  $1
author:  davidwalsh
current:  
category:  
tags:  []
docs:  
demo:  &quot; &gt;&gt; package.yml;
cd $1
git add *
git commit -m &quot;First Commit&quot;
git remote add origin gi&#116;&#64;&#103;&#105;t&#104;u&#98;&#46;&#99;&#111;m:darkwing/$1.git
</pre><p>Tada!  Done!  Now I just need to populate each file with the necessary content. MooTools FTW!</p><p><a
href="http://davidwalsh.name/mootools-forge-script">MooTools Forge / GitHub Plugin Structure Shell&nbsp;Script</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/mootools-forge-script/feed</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Run PHP Files From the Command&#160;Line</title><link>http://davidwalsh.name/php-command-line</link> <comments>http://davidwalsh.name/php-command-line#comments</comments> <pubDate>Fri, 02 Oct 2009 13:24:20 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[Shell]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=3753</guid> <description><![CDATA[I&#8217;ve been brushing up on my shell scripting lately. I just got a MacBook and never felt compelled to spend too much time with Cygwin. I&#8217;m learning quite a bit now but there are still some tasks that I&#8217;d need to accomplish sooner rather than later. I know how to accomplish the task using PHP [...]<p><a
href="http://davidwalsh.name/php-command-line">Run PHP Files From the Command&nbsp;Line</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>I&#8217;ve been brushing up on my shell scripting lately.  I just got a MacBook and never felt compelled to spend too much time with Cygwin.  I&#8217;m learning quite a bit now but there are still some tasks that I&#8217;d need to accomplish sooner rather than later.  I know how to accomplish the task using PHP so I&#8217;ve got that to my advantage.  What&#8217;s awesome is that I can quickly and easily run my PHP files from the command line.</p><h2>The Shell&nbsp;Script</h2><pre class="shell">
php doTask.php
</pre><p>I&#8217;m not sure whether I consider using PHP instead of a straight shell script as being resourceful or using PHP as a crutch.  What are your thoughts?</p><p><a
href="http://davidwalsh.name/php-command-line">Run PHP Files From the Command&nbsp;Line</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/php-command-line/feed</wfw:commentRss> <slash:comments>22</slash:comments> </item> <item><title>Automate YouTube Video and MP3 Rips with Bash Shell&#160;Scripting</title><link>http://davidwalsh.name/youtube-mp3</link> <comments>http://davidwalsh.name/youtube-mp3#comments</comments> <pubDate>Thu, 01 Oct 2009 12:21:04 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Shell]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=3698</guid> <description><![CDATA[I love listening to music while I code. Listening to music keeps me from getting too frustrated about code that isn&#8217;t working (yes, it happens) or frustrations brought on by hosting providers, clients, etc. What I&#8217;ll do is listen to Pandora, hear a song I like, look up the song on YouTube, and save the [...]<p><a
href="http://davidwalsh.name/youtube-mp3">Automate YouTube Video and MP3 Rips with Bash Shell&nbsp;Scripting</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>I love listening to music while I code.  Listening to music keeps me from getting too frustrated about code that isn&#8217;t working (yes, it happens) or frustrations brought on by hosting providers, clients, etc.  What I&#8217;ll do is listen to Pandora, hear a song I like, look up the song on YouTube, and save the YouTube link in a text file for later listening.  Having to go to YouTube every time sucks so I set out to take YouTube videos linked in a text file and download them to my computer in MP3 format.</p><h2>The Text&nbsp;File</h2><pre class="text">

http://www.youtube.com/watch?v=iYtDqHupwrg


<object width="500" height="400"><param name="movie" value="http://www.youtube.com/v/xZ23pVTPfSw&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/xZ23pVTPfSw&#038;fs=1" type="application/x-shockwave-flash" width="500" height="400" allowscriptaccess="always" allowfullscreen="true"></embed></object>


<object width="500" height="400"><param name="movie" value="http://www.youtube.com/v/Rvw1ctGWfSs&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Rvw1ctGWfSs&#038;fs=1" type="application/x-shockwave-flash" width="500" height="400" allowscriptaccess="always" allowfullscreen="true"></embed></object>


<object width="500" height="306"><param name="movie" value="http://www.youtube.com/v/IXPOHCsgWFw&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/IXPOHCsgWFw&#038;fs=1" type="application/x-shockwave-flash" width="500" height="306" allowscriptaccess="always" allowfullscreen="true"></embed></object>


<object width="500" height="400"><param name="movie" value="http://www.youtube.com/v/QF73Ypncwss&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/QF73Ypncwss&#038;fs=1" type="application/x-shockwave-flash" width="500" height="400" allowscriptaccess="always" allowfullscreen="true"></embed></object>


<object width="500" height="400"><param name="movie" value="http://www.youtube.com/v/8nBmIetx_t8&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/8nBmIetx_t8&#038;fs=1" type="application/x-shockwave-flash" width="500" height="400" allowscriptaccess="always" allowfullscreen="true"></embed></object>


<object width="500" height="400"><param name="movie" value="http://www.youtube.com/v/sw_x8XtngGM&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/sw_x8XtngGM&#038;fs=1" type="application/x-shockwave-flash" width="500" height="400" allowscriptaccess="always" allowfullscreen="true"></embed></object>

</pre><p>One link per line.</p><h2>The Bash&nbsp;Script</h2><pre class="shell">
#!/bin/sh
IFS=$'\n'
for line in `&lt; songs.txt`; do
	newfile=`youtube-dl.py -o %\(title\)s.%\(ext\)s $line | grep '^\[download\]' | cut -d ' ' -f 3-`
	ffmpeg -b 192k -i $newfile ${newfile/flv/mp3}
	rm $newfile
done
</pre><p>My script reads the file by line, downloads the YouTube video at the link provided by the text document, uses ffmpeg to rip the song into an MP3, and deleted the video.  Note that you&#8217;ll need YouTube-DL and FFMPEG to run this script;  this script is essentially a shortcut to achieve what was outlined in my post titled <a
href="http://davidwalsh.name/youtube-ffmpeg-mp3-conversion">YouTube, FFMPEG, and MP3 Conversion</a>.</p><p><a
href="http://davidwalsh.name/youtube-mp3">Automate YouTube Video and MP3 Rips with Bash Shell&nbsp;Scripting</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/youtube-mp3/feed</wfw:commentRss> <slash:comments>17</slash:comments> </item> <item><title>Creating Git&#160;Aliases</title><link>http://davidwalsh.name/git-aliases</link> <comments>http://davidwalsh.name/git-aliases#comments</comments> <pubDate>Fri, 25 Sep 2009 13:18:04 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Shell]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=3702</guid> <description><![CDATA[I create shortcuts for everything. I create variables which act as text shortcuts, shortcuts in TextMate to generate CSS/JS/HTML, and bash scripts so I don&#8217;t have to type in the same commands over and over again. So why should version control software be any different? I commit and push religiously so I create Git aliases [...]<p><a
href="http://davidwalsh.name/git-aliases">Creating Git&nbsp;Aliases</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>I create shortcuts for everything.  I create variables which act as text shortcuts, shortcuts in TextMate to generate CSS/JS/HTML, and bash scripts so I don&#8217;t have to type in the same commands over and over again.  So why should version control software be any different?  I commit and push religiously so I create Git aliases to save myself a few keystrokes.</p><h2>Sample&nbsp;Aliases</h2><pre class="git">
#make "com" alias for "commit"
git config alias.com commit

#make "co" alias for checkout
git config alias.co checkout

#make "br" alias for branch
git config alias.br branch

# When you want to see just the differences of one function in one file in two different commits
git config alias.funcdiff '!sh -c "git show \"\$1:\$3\" | sed -n \"/^[^ \t].*\$4(/,/^}/p\" > .tmp1 &#038;&#038;
        git show \"\$2:\$3\" | sed -n \"/^[^ \t].*\$4(/,/^}/p\" > .tmp2 &#038;&#038;
        git diff --no-index .tmp1 .tmp2"' -

</pre><p>These are just some sample Git aliases.  You can view more detailed (and by detailed I mean brain-numbing) examples of git aliases at the <a
href="http://git.or.cz/gitwiki/Aliases">Git Wiki</a>.</p><p><a
href="http://davidwalsh.name/git-aliases">Creating Git&nbsp;Aliases</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/git-aliases/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>PNGCRUSH a Directory of&#160;Images</title><link>http://davidwalsh.name/pngcrush-directory</link> <comments>http://davidwalsh.name/pngcrush-directory#comments</comments> <pubDate>Thu, 24 Sep 2009 12:24:15 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Shell]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=3713</guid> <description><![CDATA[One easy way of reducing website load time is by optimizing your images. PNG graphics are often more bloated than they need to be so using PNGCRUSH should be a no-brainer. PNGCRUSH&#8217;s basic usage provides only single-file-crushage but I&#8217;ve created a script that crushes PNGs in directories recursively. The Bash&#160;Script #!/bin/sh for png in `find [...]<p><a
href="http://davidwalsh.name/pngcrush-directory">PNGCRUSH a Directory of&nbsp;Images</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>One easy way of reducing website load time is by optimizing your images.  PNG graphics are often more bloated than they need to be so using PNGCRUSH should be a no-brainer.  PNGCRUSH&#8217;s basic usage provides only single-file-crushage but I&#8217;ve created a script that crushes PNGs in directories recursively.</p><h2>The Bash&nbsp;Script</h2><pre class="shell">
#!/bin/sh
for png in `find $1 -name "*.png"`;
do
	echo "crushing $png"	
	pngcrush -brute "$png" temp.png
	mv -f temp.png $png
done;
</pre><p>Do whatever you can to compress your images so that your website will load as quickly as possible.  PNGCRUSHing your images does not cause a loss of quality &#8212; only a loss of excess file size!  PNGCRUSHing my images saved over 120KB of bloated imagery for the recent redesign.</p><p><a
href="http://davidwalsh.name/pngcrush-directory">PNGCRUSH a Directory of&nbsp;Images</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/pngcrush-directory/feed</wfw:commentRss> <slash:comments>15</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced (User agent is rejected)
Database Caching 1/72 queries in 0.038 seconds using disk: basic
Object Caching 1471/1591 objects using disk: basic

Served from: davidwalsh.name @ 2012-05-24 02:18:18 -->
