<?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/"
	>

<channel>
	<title>Web-In-Sight &#187; CLI</title>
	<atom:link href="http://web-in-sight.nl/tag/cli/feed/" rel="self" type="application/rss+xml" />
	<link>http://web-in-sight.nl</link>
	<description>Inzicht in internet en werken</description>
	<lastBuildDate>Mon, 30 Jan 2012 09:00:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>nexec, distributed terminal commands</title>
		<link>http://web-in-sight.nl/2011/03/20/nexec-distributed-terminal-commands/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=nexec-distributed-terminal-commands</link>
		<comments>http://web-in-sight.nl/2011/03/20/nexec-distributed-terminal-commands/#comments</comments>
		<pubDate>Sun, 20 Mar 2011 09:01:19 +0000</pubDate>
		<dc:creator>Gerard</dc:creator>
				<category><![CDATA[All ENGLISH articles]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.gp-net.nl/?p=45</guid>
		<description><![CDATA[Update: since there&#8217;s been a change in pylib&#8217;s netexec that breaks nexec.py I&#8217;ve updated the script. Click here to download the newest version! I Developed this commandline tool to make it easier to maintain stuff on a groing amount of &#8230; <a href="http://web-in-sight.nl/2011/03/20/nexec-distributed-terminal-commands/">Lees verder <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><!--TOC--><em><strong>Update</strong>: since there&#8217;s been a change in <a href="http://codespeak.net/execnet/">pylib&#8217;s netexec</a> that breaks nexec.py I&#8217;ve updated the script. <a href="http://www.gerardjp.com/wp-content/uploads/2008/06/nexec-1.1.zip">Click here to download the newest version</a>!</em></p>
<p>I Developed <a href="http://www.gerardjp.com/wp-content/uploads/2008/06/nexec-10.tgz">this</a> commandline tool to make it easier to maintain stuff on a groing amount of servers. <strong>nexec </strong>is a tool that can help you gather ad-hoc info when it&#8217;s needed quickly. <strong>nexec</strong> is written in python, it depends on <a title="Py lib from codespeak" href="http://codespeak.net/py/dist/" target="_blank">codespeak&#8217;s pylib</a>, and does all it&#8217;s communication over SSH. The only thing you need on &#8216;the other side&#8217; is a python interpreter. (that&#8217;s right, no further libs or modules). Oh, and you need your SSH key pairs in place, otherwise it&#8217;s &#8216;password galore&#8217;.</p>
<p>Of course, the bash-ers out there would say that the same functionality can be achieved with a for loop. True! But that&#8217;s exactly what <strong>nexec</strong> does for you so you can concentrate on what you&#8217;re doing remote. And ofcourse you can have nightly cron-ed scripts in place that do this every day. But <strong>nexec</strong> aids in all those things that are not &#8216;in place&#8217;.</p>
<h2>Examples</h2>
<p>Before getting into any details, first some tricks of the &#8216;nexec&#8217; trade to get you warmed up &#8230; <img src='http://web-in-sight.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Are my server systems running the proper time:</p>
<pre>$ ./nexec.py -n 'server1 server2  server3' -c 'date'
server2: Fri May 23 16:21:18 CEST 2008
server1: Fri May 23 16:21:17 CEST 2008
server3: Fri May 23 16:21:19 CEST 2008</pre>
<p>See if all your servers are running ssh protocol 2 only:</p>
<pre>$ ./nexec.py -n 'server1 server2  server3' -c 'cat /etc/ssh/sshd_config | grep -v ^# | grep Protocol' | sort
server1: Protocol 2
server2: Protocol 2
server3: Protocol 2</pre>
<p>(You could also do a &#8220;-n ALL&#8221;, then nexec reads your server list from a config file. More on that in a minute)</p>
<p>Get a list with all different kernel versions that are running on your systems:</p>
<pre>$ ./nexec.py -n ALL -q -c 'uname -r' | sort -u
2.6.18-5-686
2.6.18.8-xen</pre>
<p>(The &#8220;-q&#8221; parameter suppresses the &#8216;per line&#8217; hostname prefix).</p>
<p>See if &#8216;john&#8217; is a member of the sudo group on servers 1 and 2:</p>
<pre>./nexec.py -v -q -n 'server1 server2' -c 'cat /etc/group | grep sudo | grep -v john'
Host:  server1.example.com
sudo:x:27:jane,jerry
Host:  server2.example.com
sudo:x:27:jane</pre>
<p>(The&#8221;-v&#8221; adds the &#8220;Host: &#8230;.&#8221; header, per server output. Note that &#8220;-v&#8221; and &#8220;-q&#8221; are interchangeable)</p>
<p>As you can see, by combining local and remote greps and using the -v and/or -q parameters there are some interesting ways to obtain live data from your server.</p>
<p>Lets look at the configuration.</p>
<h2>Configuration</h2>
<p>Run without parms, <strong>nexec</strong> shows help output. Furthermore the only two files <strong>nexec</strong> depends on (and not even necessarily) are a &#8220;~/.nexec.conf&#8221; file and a possible &#8220;~/.ssh/config&#8221;.</p>
<p>The &#8220;~/.nexec.conf&#8221; does not contain much, just &#8220;key: value&#8221; pairs under a hosts section. The actual &#8216;value&#8217; is only obtained when using the &#8220;-v&#8221; option to display the header above each server output &#8220;<em>Host: server1.example.com</em>&#8220;.</p>
<pre>$ cat .nexec.conf
[hosts]
server1:   server1.example.com
server2:   server2.example.com
#server3:   server3.example.com</pre>
<p>Other then that, <strong>nexec</strong> simply expands &#8220;-c ALL&#8221; to all available keys under the &#8220;[hosts]&#8221; section, skipping the usual hashsign &#8216;#&#8217; being a comment. In this case the &#8220;ALL&#8221; parameter given to &#8220;-c&#8221; would be expanded to &#8220;server1 server2&#8243; in the previous example. After that the full name is taken from the &#8220;~.ssh/config&#8221; file.</p>
<pre>$ cat .ssh/config
# server1
Host server1
Hostname server1.example.com
User john
Port 4321
# server2
Host server2
Hostname server2.example.com
User john
<a href="http://www.gerardjp.com/wp-content/uploads/2008/06/nexec-1.0.tgz"></a>Port 4321</pre>
<p>I deliberately left all that in there so other usernames and port numbers can be specified. Besides, that&#8217;s all access related and shouldn&#8217;t be anywhere else anyway.</p>
<p>Then one more note on the &#8220;-q&#8221; and &#8220;-v&#8221; option. What they basically do is mark (or suppress mark&#8217;s) on the output that get&#8217;s returned. So you can mark output per server adding the &#8220;-v&#8221;, and output get&#8217;s marked per line (default) if not suppressed with &#8220;-q&#8221;.</p>
<h2>Download</h2>
<p>The script can be downloaded here: <a href="http://www.gerardjp.com/wp-content/uploads/2008/06/nexec-10.tgz">nexec-10.tgz</a></p>
<p>Set the &#8216;execute&#8217; bit with chmod and put it in your $PATH somewhere. And for the &#8220;ALL&#8221; parameter, set up the config file as the example shows in the <a title="TOC: Configuration" href="#toc-configuration">Configuration</a> section.</p>
<h3>Gotcha&#8217;s</h3>
<p>Escape your backticks with with a backslash if you want remote expansion.</p>
<p>This runs the uname part locally and then sends the command to the other side.</p>
<pre>$ nexec.py -n ALL -c "date | mailx -s `uname -n` root"</pre>
<p>This also executes the uname command on the other side.</p>
<pre>$ nexec.py -n ALL -c "date | mailx -s \`uname -n\` root"</pre>
<h2>Todo</h2>
<p>There&#8217;s two things still on my list.</p>
<ul>
<li>Catch a non-existing hostname when taken from the &#8220;.ssh/config&#8221; file. The script breaks if a host is not resolvable. (Being a sysadmin you should know what your doing .. <img src='http://web-in-sight.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
<li>Make the &#8220;<em>Host: server1.example.com</em>&#8221; header not show when no output is returned from a host. That is when using the &#8220;-c ALL&#8221;.</li>
</ul>
<p>New tricks might be added in the future, so if there&#8217;s stuff that you think should be added drop me a reply.</p>
<p>That&#8217;s all folks &#8230;</p>
<div class="AWD_like_button "><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fweb-in-sight.nl%2F2011%2F03%2F20%2Fnexec-distributed-terminal-commands%2F&amp;send=false&amp;layout=button_count&amp;width=&amp;show_faces=false&amp;action=recommend&amp;colorscheme=light&amp;font=arial&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:px; height:21px;" allowTransparency="true"></iframe></div>]]></content:encoded>
			<wfw:commentRss>http://web-in-sight.nl/2011/03/20/nexec-distributed-terminal-commands/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

