<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Library on Nyanmo main blog</title>
    <link>https://www.nyanmo.info/tags/library/</link>
    <description>Recent content in Library on Nyanmo main blog</description>
    <generator>Hugo</generator>
    <language>ja</language>
    <lastBuildDate>Wed, 09 Sep 2026 02:02:52 +0900</lastBuildDate>
    <atom:link href="https://www.nyanmo.info/tags/library/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>pexpect において、標準出力にログを出力させながら、端末の出力に関係なくコマンドを実行させたいとき</title>
      <link>https://www.nyanmo.info/posts/other/python/makepexpectnottoexpect/</link>
      <pubDate>Wed, 09 Sep 2026 02:02:52 +0900</pubDate>
      <guid>https://www.nyanmo.info/posts/other/python/makepexpectnottoexpect/</guid>
      <description>&lt;h2 id=&#34;この記事を作った動機&#34;&gt;この記事を作った動機&lt;/h2&gt;
&lt;p&gt;　&lt;a href=&#34;https://www.nyanmo.info/posts/idea/research/onenotealternativecreation/&#34;&gt;Onenote代替品の作成&lt;/a&gt;の研究の一環で、pexpect を使って端末のセッションを維持させながらとにかくコマンドを実行させたいということがあり、その過程で試行錯誤があったため記録したい。&lt;/p&gt;
&lt;h2 id=&#34;現状使っているもの&#34;&gt;現状使っているもの&lt;/h2&gt;
&lt;p&gt;　以下は現状使っている実装の参考例である。一定時間置いたあとに、何でもマッチングする&lt;code&gt;expect&lt;/code&gt;を配置しているのは、標準出力である&lt;code&gt;stdout&lt;/code&gt;に対して、コマンドの実行結果を吐き出させたいためである。作ったセッション内のターミナルに何が出力されるかわからないが、とにかくコマンドを実行させて、その結果を出力することに以下のスクリプトは特化している。&lt;/p&gt;
&lt;p&gt;　待ち時間は適宜調整する必要がある。&lt;/p&gt;
&lt;h3 id=&#34;スクリプト本体&#34;&gt;スクリプト本体&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; pexpect&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;time&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;sys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; pexpect&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;spawn(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/bin/bash&amp;#34;&lt;/span&gt;,timeout&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;, encoding&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;logfile_read &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;stdout
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ls&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sleep(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;expect(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;.+&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gcc&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sleep(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;expect(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;.+&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;実行結果&#34;&gt;実行結果&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python main1.py
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ls
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ⠀aaaa  ⠀main.py  ⠀main1.py  ⠀readme.md  ⠀test/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gcc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# gcc: fatal error: 入力ファイルがありません&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# compilation terminated.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;追記-2026916&#34;&gt;追記 (2026/9/16)&lt;/h3&gt;
&lt;p&gt;　このやり方は非常に簡易的にしか動作せず、副作用があることが分かった。具体的には&amp;quot;.+&amp;ldquo;でexpectさせるとログが出てくるのは、pexpectが期待した文字列を待機している状態になるからであることが分かった。つまるところ、タイムアウトに引っかかると例外を出して強制終了してしまう。&lt;/p&gt;
&lt;p&gt;　それを防ぐには、pexpectにおいては、waitという専用の関数があるため、それを利用することができることが分かった。ただこれだとログが出てこない(&amp;rdquo;.*&amp;ldquo;と同じ挙動になる)ため、なにかさらに工夫が必要そうなことが分かっている。&lt;/p&gt;
&lt;p&gt;　また、pexpect にて同じ端末に出力を出させると端末の表示がぐちゃぐちゃになってしまう。最近考えていることとして個別にファイルとしてlogをテキストファイルとして書き出させてそれを&lt;code&gt;watch -n 0.1 &amp;quot;cat log | tail -n 10&amp;quot;&lt;/code&gt;みたいにすればよいのではないかと思い始めている。&lt;/p&gt;
&lt;h2 id=&#34;うまくいかなかったこと&#34;&gt;うまくいかなかったこと&lt;/h2&gt;
&lt;h3 id=&#34;単にsendlineする&#34;&gt;単に&lt;code&gt;sendline&lt;/code&gt;する&lt;/h3&gt;
&lt;p&gt;　単に&lt;code&gt;sendline&lt;/code&gt;すると、コマンド自体は実行されるが、一切標準出力にログが出力されないことになる。&lt;/p&gt;
&lt;h4 id=&#34;スクリプト本体-1&#34;&gt;スクリプト本体&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; pexpect
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;sys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; pexpect&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;spawn(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/bin/bash&amp;#34;&lt;/span&gt;,timeout&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;, encoding&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;logfile_read &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;stdout
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ls&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sleep(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;echo test &amp;gt; test1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sleep(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;実行結果-1&#34;&gt;実行結果&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python main2.py 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 何も出てこない&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat test1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;エンコードを指定しない&#34;&gt;エンコードを指定しない&lt;/h3&gt;
&lt;p&gt;　端末のセッションを作るときに、文字コードを明示しなかった場合、そもそもスクリプトを実行できないことがある。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
