Lacking Natural Simplicity (Posts about logging)
https://tkurtbond.github.io/categories/logging.atom
2024-01-23T18:49:40Z
T. Kurt Bond
Nikola
Logging the output of long commands run multiple times
https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/
2021-07-07T12:47:25-04:00
2021-07-07T12:47:25-04:00
T. Kurt Bond
<p>I often run commands that produce a lot of output that needs to saved
for debugging, and often the commands have to be repeated multiple
times to get things to work. For example, building software from
source, often using the familiar <code class="docutils literal">./configure; make; make install</code>
paradigm.</p>
<p>So, the first thing is to try is to use the venerable <span class="command">tee</span> command.</p>
<div class="code"><pre class="code bash"><a id="rest_code_1e31e2b85af64908b9d390d9f64fdd7c-1" name="rest_code_1e31e2b85af64908b9d390d9f64fdd7c-1" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_1e31e2b85af64908b9d390d9f64fdd7c-1"></a>./configure<span class="w"> </span><span class="m">2</span>><span class="p">&</span><span class="m">1</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>tee<span class="w"> </span>Log.configure
<a id="rest_code_1e31e2b85af64908b9d390d9f64fdd7c-2" name="rest_code_1e31e2b85af64908b9d390d9f64fdd7c-2" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_1e31e2b85af64908b9d390d9f64fdd7c-2"></a>make<span class="w"> </span><span class="m">2</span>><span class="p">&</span><span class="m">1</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>tee<span class="w"> </span>Log.make
<a id="rest_code_1e31e2b85af64908b9d390d9f64fdd7c-3" name="rest_code_1e31e2b85af64908b9d390d9f64fdd7c-3" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_1e31e2b85af64908b9d390d9f64fdd7c-3"></a>make<span class="w"> </span>install<span class="w"> </span><span class="m">2</span>><span class="p">&</span><span class="m">1</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>tee<span class="w"> </span>Log.make-install
</pre></div>
<p>To make the log files easy to find I use a <span class="file">Log.</span> prefix.</p>
<p>But I often need to run the commands multiple times, and want to save
each run under a new filename, so if the filename already exists I
want to add a number to the end and then increment the number until I
find one that hasn't been used. And I'd like the filename to have the
date in YYYY-MM-DD format, so the resulting names look like
<span class="file">Log.make-install-2021-07-07_2</span>.</p>
<p>So I wrote a bash function <span class="command">incf</span> (increment filename) to put in
<span class="file">.bashrc</span> that generates such a name:</p>
<div class="code"><pre class="code bash"><a id="rest_code_9335958ced034ccabde8d1fc693cd728-1" name="rest_code_9335958ced034ccabde8d1fc693cd728-1" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-1"></a>incf<span class="w"> </span><span class="o">()</span><span class="w"> </span><span class="o">{</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-2" name="rest_code_9335958ced034ccabde8d1fc693cd728-2" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-2"></a><span class="w"> </span><span class="c1"># Construct a filename from PREFIX, "_YYYY-MM-DD", optionally _N (where N</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-3" name="rest_code_9335958ced034ccabde8d1fc693cd728-3" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-3"></a><span class="w"> </span><span class="c1"># is 1 or greater) if the filename already exists, and optionally SUFFIX.</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-4" name="rest_code_9335958ced034ccabde8d1fc693cd728-4" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-4"></a><span class="w"> </span><span class="c1"># Example: "incf file .tar.gz" results in "file_2021-07-07.tar.gz", or</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-5" name="rest_code_9335958ced034ccabde8d1fc693cd728-5" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-5"></a><span class="w"> </span><span class="c1"># "file_2021-07-07_N.tar.gz" if "file_2021-07-07.tar.gz" already exists,</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-6" name="rest_code_9335958ced034ccabde8d1fc693cd728-6" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-6"></a><span class="w"> </span><span class="c1"># where N is 1 or greater.</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-7" name="rest_code_9335958ced034ccabde8d1fc693cd728-7" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-7"></a><span class="w"> </span><span class="nb">local</span><span class="w"> </span>prefix<span class="w"> </span>suffix<span class="w"> </span>fileprefix<span class="w"> </span>i<span class="w"> </span>testname<span class="w"> </span>sep1<span class="w"> </span>sep2
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-8" name="rest_code_9335958ced034ccabde8d1fc693cd728-8" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-8"></a><span class="w"> </span><span class="nv">prefix</span><span class="o">=</span><span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-9" name="rest_code_9335958ced034ccabde8d1fc693cd728-9" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-9"></a><span class="w"> </span><span class="nv">suffix</span><span class="o">=</span><span class="s2">"</span><span class="nv">$2</span><span class="s2">"</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-10" name="rest_code_9335958ced034ccabde8d1fc693cd728-10" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-10"></a><span class="w"> </span><span class="nv">sep1</span><span class="o">=</span><span class="s2">"_"</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-11" name="rest_code_9335958ced034ccabde8d1fc693cd728-11" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-11"></a><span class="w"> </span><span class="nv">sep2</span><span class="o">=</span><span class="s2">"_"</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-12" name="rest_code_9335958ced034ccabde8d1fc693cd728-12" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-12"></a><span class="w"> </span><span class="nv">fileprefix</span><span class="o">=</span><span class="s2">"</span><span class="si">${</span><span class="nv">prefix</span><span class="si">}${</span><span class="nv">sep1</span><span class="si">}</span><span class="k">$(</span>date<span class="w"> </span>+%F<span class="k">)</span><span class="s2">"</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-13" name="rest_code_9335958ced034ccabde8d1fc693cd728-13" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-13"></a><span class="w"> </span><span class="nb">let</span><span class="w"> </span><span class="nv">i</span><span class="o">=</span><span class="m">0</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-14" name="rest_code_9335958ced034ccabde8d1fc693cd728-14" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-14"></a><span class="w"> </span><span class="c1"># The zeroth filename doesn't have the number.</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-15" name="rest_code_9335958ced034ccabde8d1fc693cd728-15" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-15"></a><span class="w"> </span><span class="nv">testname</span><span class="o">=</span><span class="s2">"</span><span class="si">${</span><span class="nv">fileprefix</span><span class="si">}${</span><span class="nv">suffix</span><span class="si">}</span><span class="s2">"</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-16" name="rest_code_9335958ced034ccabde8d1fc693cd728-16" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-16"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="nb">true</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-17" name="rest_code_9335958ced034ccabde8d1fc693cd728-17" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-17"></a><span class="w"> </span><span class="k">do</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-18" name="rest_code_9335958ced034ccabde8d1fc693cd728-18" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-18"></a><span class="w"> </span><span class="o">[</span><span class="w"> </span>!<span class="w"> </span>-e<span class="w"> </span><span class="s2">"</span><span class="nv">$testname</span><span class="s2">"</span><span class="w"> </span><span class="o">]</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="k">break</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-19" name="rest_code_9335958ced034ccabde8d1fc693cd728-19" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-19"></a><span class="w"> </span><span class="o">((</span>i++<span class="o">))</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-20" name="rest_code_9335958ced034ccabde8d1fc693cd728-20" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-20"></a><span class="w"> </span><span class="nv">testname</span><span class="o">=</span><span class="s2">"</span><span class="si">${</span><span class="nv">fileprefix</span><span class="si">}${</span><span class="nv">sep2</span><span class="si">}${</span><span class="nv">i</span><span class="si">}${</span><span class="nv">suffix</span><span class="si">}</span><span class="s2">"</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-21" name="rest_code_9335958ced034ccabde8d1fc693cd728-21" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-21"></a><span class="w"> </span><span class="k">done</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-22" name="rest_code_9335958ced034ccabde8d1fc693cd728-22" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-22"></a><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"</span><span class="nv">$testname</span><span class="s2">"</span>
<a id="rest_code_9335958ced034ccabde8d1fc693cd728-23" name="rest_code_9335958ced034ccabde8d1fc693cd728-23" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_9335958ced034ccabde8d1fc693cd728-23"></a><span class="o">}</span>
</pre></div>
<p>And then I wrote a bash function that uses <span class="command">incf</span> to generate
the <span class="file">Log.</span> filename, potentially in a different directory:</p>
<div class="code"><pre class="code bash"><a id="rest_code_4f4600014e61447fbba8e8f676adc0a2-1" name="rest_code_4f4600014e61447fbba8e8f676adc0a2-1" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_4f4600014e61447fbba8e8f676adc0a2-1"></a>logf<span class="w"> </span><span class="o">()</span><span class="w"> </span><span class="o">{</span>
<a id="rest_code_4f4600014e61447fbba8e8f676adc0a2-2" name="rest_code_4f4600014e61447fbba8e8f676adc0a2-2" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_4f4600014e61447fbba8e8f676adc0a2-2"></a><span class="w"> </span><span class="c1"># Construct a filename, possibly in another directory, that starts with</span>
<a id="rest_code_4f4600014e61447fbba8e8f676adc0a2-3" name="rest_code_4f4600014e61447fbba8e8f676adc0a2-3" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_4f4600014e61447fbba8e8f676adc0a2-3"></a><span class="w"> </span><span class="c1"># "Log." and ends with "YYYY-MM-DD" and optionally "_N", where N is 1 or</span>
<a id="rest_code_4f4600014e61447fbba8e8f676adc0a2-4" name="rest_code_4f4600014e61447fbba8e8f676adc0a2-4" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_4f4600014e61447fbba8e8f676adc0a2-4"></a><span class="w"> </span><span class="c1"># greater, if the filename already exists.</span>
<a id="rest_code_4f4600014e61447fbba8e8f676adc0a2-5" name="rest_code_4f4600014e61447fbba8e8f676adc0a2-5" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_4f4600014e61447fbba8e8f676adc0a2-5"></a><span class="w"> </span><span class="nb">local</span><span class="w"> </span>dn<span class="w"> </span>bn<span class="w"> </span>fn
<a id="rest_code_4f4600014e61447fbba8e8f676adc0a2-6" name="rest_code_4f4600014e61447fbba8e8f676adc0a2-6" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_4f4600014e61447fbba8e8f676adc0a2-6"></a><span class="w"> </span><span class="nv">dn</span><span class="o">=</span><span class="s2">"</span><span class="k">$(</span>dirname<span class="w"> </span><span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span><span class="k">)</span><span class="s2">"</span>
<a id="rest_code_4f4600014e61447fbba8e8f676adc0a2-7" name="rest_code_4f4600014e61447fbba8e8f676adc0a2-7" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_4f4600014e61447fbba8e8f676adc0a2-7"></a><span class="w"> </span><span class="nv">bn</span><span class="o">=</span><span class="s2">"Log.</span><span class="k">$(</span>basename<span class="w"> </span><span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span><span class="k">)</span><span class="s2">"</span>
<a id="rest_code_4f4600014e61447fbba8e8f676adc0a2-8" name="rest_code_4f4600014e61447fbba8e8f676adc0a2-8" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_4f4600014e61447fbba8e8f676adc0a2-8"></a><span class="w"> </span><span class="nv">fn</span><span class="o">=</span><span class="s2">"</span><span class="k">$(</span>incf<span class="w"> </span><span class="s2">"</span><span class="nv">$dn</span><span class="s2">/</span><span class="nv">$bn</span><span class="s2">"</span><span class="k">)</span><span class="s2">"</span>
<a id="rest_code_4f4600014e61447fbba8e8f676adc0a2-9" name="rest_code_4f4600014e61447fbba8e8f676adc0a2-9" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_4f4600014e61447fbba8e8f676adc0a2-9"></a><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="nv">$fn</span>
<a id="rest_code_4f4600014e61447fbba8e8f676adc0a2-10" name="rest_code_4f4600014e61447fbba8e8f676adc0a2-10" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_4f4600014e61447fbba8e8f676adc0a2-10"></a><span class="o">}</span>
</pre></div>
<p>And then I wrote a <span class="command">log</span> command that uses <span class="command">logf</span>
and tees its input into that file:</p>
<div class="code"><pre class="code bash"><a id="rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-1" name="rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-1" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-1"></a>log<span class="w"> </span><span class="o">()</span><span class="w"> </span><span class="o">{</span>
<a id="rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-2" name="rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-2" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-2"></a><span class="w"> </span><span class="c1"># tee the input into a log file.</span>
<a id="rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-3" name="rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-3" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-3"></a><span class="w"> </span>tee<span class="w"> </span><span class="k">$(</span>logf<span class="w"> </span><span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span><span class="k">)</span>
<a id="rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-4" name="rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-4" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_ab8cbf1c22dd43dbb3fd84ce5797adb0-4"></a><span class="o">}</span>
</pre></div>
<p>So running <code class="docutils literal">./configure <span class="pre">2>&1</span> | log ~/tmp/configure</code> generates a file
<span class="file">Log.configure_2021-07-07</span> in the <span class="file">~/tmp</span> directory.</p>
<p>But what if I specify a lot of options to the command, and would like
record if it in the log file, so if I get interrupted and then come
back some time later I can use the same command?</p>
<p>First I wrote a base function, <span class="command">cleanname</span>, that takes a string and
converts it to something that should be safe to use as a filename.</p>
<div class="code"><pre class="code bash"><a id="rest_code_8039761b61ed4ac1bbf6929853e9d86d-1" name="rest_code_8039761b61ed4ac1bbf6929853e9d86d-1" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_8039761b61ed4ac1bbf6929853e9d86d-1"></a>cleanname<span class="w"> </span><span class="o">()</span><span class="w"> </span><span class="o">{</span>
<a id="rest_code_8039761b61ed4ac1bbf6929853e9d86d-2" name="rest_code_8039761b61ed4ac1bbf6929853e9d86d-2" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_8039761b61ed4ac1bbf6929853e9d86d-2"></a><span class="w"> </span><span class="c1"># Clean up a string so it is (relatively) safe to use as a filename.</span>
<a id="rest_code_8039761b61ed4ac1bbf6929853e9d86d-3" name="rest_code_8039761b61ed4ac1bbf6929853e9d86d-3" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_8039761b61ed4ac1bbf6929853e9d86d-3"></a><span class="w"> </span><span class="nb">local</span><span class="w"> </span><span class="nv">cmd</span><span class="o">=</span><span class="s2">"</span><span class="nv">$*</span><span class="s2">"</span><span class="w"> </span>name
<a id="rest_code_8039761b61ed4ac1bbf6929853e9d86d-4" name="rest_code_8039761b61ed4ac1bbf6929853e9d86d-4" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_8039761b61ed4ac1bbf6929853e9d86d-4"></a><span class="w"> </span><span class="nv">name</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span><span class="w"> </span><span class="s2">"</span><span class="nv">$cmd</span><span class="s2">"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span><span class="s1">'s/[ =";?*&^%$#@!~`|()<>]/-/g'</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="se">\</span>
<a id="rest_code_8039761b61ed4ac1bbf6929853e9d86d-5" name="rest_code_8039761b61ed4ac1bbf6929853e9d86d-5" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_8039761b61ed4ac1bbf6929853e9d86d-5"></a><span class="w"> </span>sed<span class="w"> </span><span class="s2">"s#[/']#-#g"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-E<span class="w"> </span><span class="s1">'s/--+/-/g'</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="se">\</span>
<a id="rest_code_8039761b61ed4ac1bbf6929853e9d86d-6" name="rest_code_8039761b61ed4ac1bbf6929853e9d86d-6" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_8039761b61ed4ac1bbf6929853e9d86d-6"></a><span class="w"> </span>sed<span class="w"> </span>-E<span class="w"> </span><span class="s1">'s/(^[-.]+|-+$)//g'</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="se">\</span>
<a id="rest_code_8039761b61ed4ac1bbf6929853e9d86d-7" name="rest_code_8039761b61ed4ac1bbf6929853e9d86d-7" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_8039761b61ed4ac1bbf6929853e9d86d-7"></a><span class="w"> </span>sed<span class="w"> </span>-E<span class="w"> </span><span class="s1">'s/\.\.\.*/./g'</span><span class="k">)</span>
<a id="rest_code_8039761b61ed4ac1bbf6929853e9d86d-8" name="rest_code_8039761b61ed4ac1bbf6929853e9d86d-8" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_8039761b61ed4ac1bbf6929853e9d86d-8"></a><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"</span><span class="nv">$name</span><span class="s2">"</span>
<a id="rest_code_8039761b61ed4ac1bbf6929853e9d86d-9" name="rest_code_8039761b61ed4ac1bbf6929853e9d86d-9" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_8039761b61ed4ac1bbf6929853e9d86d-9"></a><span class="o">}</span>
</pre></div>
<p>Then I wrote a bash function, <span class="command">exlog</span>, to use the whole
command with its options as part of the filename (constructed with
<span class="command">cleanname</span>, and also include the whole command in the log output:</p>
<div class="code"><pre class="code bash"><a id="rest_code_eed27f36decf4f3fa2a8ede786d10a79-1" name="rest_code_eed27f36decf4f3fa2a8ede786d10a79-1" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_eed27f36decf4f3fa2a8ede786d10a79-1"></a>exlog<span class="w"> </span><span class="o">()</span><span class="w"> </span><span class="o">{</span>
<a id="rest_code_eed27f36decf4f3fa2a8ede786d10a79-2" name="rest_code_eed27f36decf4f3fa2a8ede786d10a79-2" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_eed27f36decf4f3fa2a8ede786d10a79-2"></a><span class="w"> </span><span class="c1"># Execute a shell command and log it to "Log.<cmd-as-safe-filename>"</span>
<a id="rest_code_eed27f36decf4f3fa2a8ede786d10a79-3" name="rest_code_eed27f36decf4f3fa2a8ede786d10a79-3" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_eed27f36decf4f3fa2a8ede786d10a79-3"></a><span class="w"> </span><span class="nb">local</span><span class="w"> </span><span class="nv">cmd</span><span class="o">=</span><span class="s2">"</span><span class="nv">$*</span><span class="s2">"</span><span class="w"> </span><span class="nv">name</span><span class="o">=</span><span class="s2">"</span><span class="k">$(</span>cleanname<span class="w"> </span><span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span><span class="k">)</span><span class="s2">"</span>
<a id="rest_code_eed27f36decf4f3fa2a8ede786d10a79-4" name="rest_code_eed27f36decf4f3fa2a8ede786d10a79-4" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_eed27f36decf4f3fa2a8ede786d10a79-4"></a><span class="w"> </span><span class="nv">name</span><span class="o">=</span><span class="s2">"</span><span class="k">$(</span>logf<span class="w"> </span><span class="nv">$name</span><span class="k">)</span><span class="s2">"</span>
<a id="rest_code_eed27f36decf4f3fa2a8ede786d10a79-5" name="rest_code_eed27f36decf4f3fa2a8ede786d10a79-5" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_eed27f36decf4f3fa2a8ede786d10a79-5"></a><span class="w"> </span><span class="nb">printf</span><span class="w"> </span><span class="s1">'Logging to %s\n'</span><span class="w"> </span><span class="s2">"</span><span class="nv">$name</span><span class="s2">"</span>
<a id="rest_code_eed27f36decf4f3fa2a8ede786d10a79-6" name="rest_code_eed27f36decf4f3fa2a8ede786d10a79-6" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_eed27f36decf4f3fa2a8ede786d10a79-6"></a><span class="w"> </span><span class="o">(</span><span class="nb">echo</span><span class="w"> </span><span class="s2">"cmd was: </span><span class="nv">$cmd</span><span class="s2">"</span><span class="p">;</span><span class="w"> </span><span class="nb">time</span><span class="w"> </span><span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span><span class="o">)</span><span class="w"> </span><span class="m">2</span>><span class="p">&</span><span class="m">1</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>tee<span class="w"> </span><span class="nv">$name</span>
<a id="rest_code_eed27f36decf4f3fa2a8ede786d10a79-7" name="rest_code_eed27f36decf4f3fa2a8ede786d10a79-7" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_eed27f36decf4f3fa2a8ede786d10a79-7"></a><span class="o">}</span>
</pre></div>
<p>So running the command</p>
<div class="code"><pre class="code bash"><a id="rest_code_1c24fb9803df4406a447d183dd70ea8f-1" name="rest_code_1c24fb9803df4406a447d183dd70ea8f-1" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_1c24fb9803df4406a447d183dd70ea8f-1"></a>exlog<span class="w"> </span>../configure<span class="w"> </span>--prefix<span class="o">=</span>/Users/tkb/sw/versions/groff/git
</pre></div>
<p>produces the file</p>
<div class="code"><pre class="code text"><a id="rest_code_e62052f01a4f47de9464d9b36be902d2-1" name="rest_code_e62052f01a4f47de9464d9b36be902d2-1" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_e62052f01a4f47de9464d9b36be902d2-1"></a>Log.configure-prefix-Users-tkb-sw-versions-groff-git_2021-07-07
</pre></div>
<p>and it contains the line</p>
<div class="code"><pre class="code text"><a id="rest_code_cf6b315b31e14382bb2325cd4fb874fe-1" name="rest_code_cf6b315b31e14382bb2325cd4fb874fe-1" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_cf6b315b31e14382bb2325cd4fb874fe-1"></a>cmd was: ../configure --prefix=/Users/tkb/sw/versions/groff/git
</pre></div>
<p>and running it again produces the file</p>
<div class="code"><pre class="code text"><a id="rest_code_12778cbd72f94443b5f88d43d2e1c68a-1" name="rest_code_12778cbd72f94443b5f88d43d2e1c68a-1" href="https://tkurtbond.github.io/posts/2021/07/07/logging-the-output-of-long-commands-run-multiple-times/#rest_code_12778cbd72f94443b5f88d43d2e1c68a-1"></a>Log.configure-prefix-Users-tkb-sw-versions-groff-git_2021-07-07_1
</pre></div>
<p>This code is available in a <a class="reference external" href="https://gist.github.com/tkurtbond/23255fede737eec89b1fd0e011566cb1">gist</a>.</p>
<p><em>Last edited: 2021-07-09 15:30:53 EDT</em></p>
<!-- Local Variables:
time-stamp-format: "%04y-%02m-%02d %02H:%02M:%02S %Z"
time-stamp-start: "\\*Last edited:[ \t]+\\\\?"
time-stamp-end: "\\*\\\\?\n"
time-stamp-line-limit: -20
End: -->