「Windowsでエクスプローラーからフォルダを各種ターミナルで開く」の版間の差分

Notion-MW
Notion-MW
75行目: 75行目:
これを防ぐ方法はいくつかある。ちなみに、<code>%%</code>でのエスケープというのはバッチファイルの中だけの話で、今回の場面では以下より簡単なエスケープ方法は多分ないと思う。
これを防ぐ方法はいくつかある。ちなみに、<code>%%</code>でのエスケープというのはバッチファイルの中だけの話で、今回の場面では以下より簡単なエスケープ方法は多分ないと思う。


<ul>
<ol style="list-style-type: decimal;">
<li><p>既に定義されているかもしれない環境変数をバックアップし、一時的にその中身を<code>%</code>に変えて使用することでリテラル文字としての<code>%</code>を表現し、後で元に戻す。</p>
<li><p>既に定義されているかもしれない環境変数をバックアップし、一時的にその中身を<code>%</code>に変えて使用することでリテラル文字としての<code>%</code>を表現し、後で元に戻す。</p>
<p>すなわち、<code>MY_PERCENT</code>のような変数の中身をバックアップし、<code>MY_PERCENT</code>の中身を<code>%</code>に変え、未知の文字列中の<code>%</code>をすべて<code>%MY_PERCENT%</code>にすることで<strong>この部分が置換によって</strong><strong><code>%</code></strong><strong>に変わるのを利用して</strong><code>%</code>をそのまま渡すということである(環境変数の置換は左から順に行われるため、たとえば<code>%MY_PERCENT%PATH%MY_PERCENT%</code>の<code>%PATH%</code>が置換されることはない)。受け渡しが終わったら<code>MY_PERCENT</code>の中身を復元する。</p>
<p>すなわち、<code>MY_PERCENT</code>のような変数の中身をバックアップし、<code>MY_PERCENT</code>の中身を<code>%</code>に変え、未知の文字列中の<code>%</code>をすべて<code>%MY_PERCENT%</code>にすることで<strong>この部分が置換によって</strong><strong><code>%</code></strong><strong>に変わるのを利用して</strong><code>%</code>をそのまま渡すということである(環境変数の置換は左から順に行われるため、たとえば<code>%MY_PERCENT%PATH%MY_PERCENT%</code>の<code>%PATH%</code>が置換されることはない)。受け渡しが終わったら<code>MY_PERCENT</code>の中身を復元する。</p>
98行目: 98行目:
</li>
</li>
<li>ただ、<code>&#61;&#61;%</code>を<code>%</code>に置換するという操作はPowerShellやshにとっては容易でもcmdにとっては不可能に近いので、最終的な呼び出し先がcmdであるときには採用しづらい。</li></ul>
<li>ただ、<code>&#61;&#61;%</code>を<code>%</code>に置換するという操作はPowerShellやshにとっては容易でもcmdにとっては不可能に近いので、最終的な呼び出し先がcmdであるときには採用しづらい。</li></ul>
</li></ul>
</li></ol>


また、今回の記事ではcmdやvbsのRunを経由してコマンドを実行しているものが多くあるが、<strong>このスクリプトの内容自体もエスケープが必要</strong>である。つまり、例えば<code>cmd /c</code>の内側に<code>$mypath.Replace(&#39;%&#39;,&#39;%MY_PERCENT%&#39;)</code>というPowershellコードが含まれるなら、<code>&#39;,&#39;</code>や<code>MY_PERCENT</code>という環境変数が定義されていた時にその部分が置換されてしまう。これを回避するのはそこまで難しくなく、この例であれば<code>$mypath.Replace(&#39;%&#39;.Trim(&#39;&#61;&#39;),&#39;%&#39;.Trim(&#39;&#61;&#39;)+&#39;MY_PERCENT%&#39;)</code>のように<code>&#61;</code>を含む無意味なコードを挿入すればよい。また、<code>%</code>をいったん<code>&#61;&#61;%</code>にしている部分に関しては、<code>&#61;&#61;%</code>ではなく<code>&#61;&#61;%&#61;&#61;</code>にすることで問題を避けられるだろう。無駄に複雑になるのでスクリプト例ではそのような措置はしていない。
また、今回の記事ではcmdやvbsのRunを経由してコマンドを実行しているものが多くあるが、<strong>このスクリプトの内容自体もエスケープが必要</strong>である。つまり、例えば<code>cmd /c</code>の内側に<code>$mypath.Replace(&#39;%&#39;,&#39;%MY_PERCENT%&#39;)</code>というPowershellコードが含まれるなら、<code>&#39;,&#39;</code>や<code>MY_PERCENT</code>という環境変数が定義されていた時にその部分が置換されてしまう。これを回避するのはそこまで難しくなく、この例であれば<code>$mypath.Replace(&#39;%&#39;.Trim(&#39;&#61;&#39;),&#39;%&#39;.Trim(&#39;&#61;&#39;)+&#39;MY_PERCENT%&#39;)</code>のように<code>&#61;</code>を含む無意味なコードを挿入すればよい。また、<code>%</code>をいったん<code>&#61;&#61;%</code>にしている部分に関しては、<code>&#61;&#61;%</code>ではなく<code>&#61;&#61;%&#61;&#61;</code>にすることで問題を避けられるだろう。無駄に複雑になるのでスクリプト例ではそのような措置はしていない。