1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WSL のシェルから Windows のバッチファイルを管理者権限で起動するシェルスクリプトの作成で得られたバッドノウハウ

Posted at

タイトルが長いのはご容赦ください。ここでは、WSL で利用するシェルスクリプトを作成した時に得られたバッドノウハウを 3 点紹介します。 このシェルスクリプトを作成する時は知らなかったのですが、Sudo for WSL (wsl-sudo)1 というものがあります。試してみたことはありません。バッドノウハウよりも今使えるものが欲しいという方はこちらを試してみてはどうでしょうか?

作成したシェルスクリプトの概要

  • WSL のコマンドシェル or シェルスクリプトから起動することを想定
  • 引数で指定されたバッチファイルを管理者権限で起動します
  • バッチファイルは Windows の %TEMP% ディレクトリに存在するものとします

作成したシェルスクリプト2

     1	#!/bin/sh
     2	runfile="$1"
     3	cd /mnt/c
     4	
     5	u_psexe="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
     6	m_psexe=$(wslpath -a -m "$u_psexe")
     7	
     8	u_cmdexe="/mnt/c/Windows/System32/cmd.exe"
     9	m_cmdexe=$(wslpath -a -m "$u_cmdexe")
    10	
    11	# Get value of %TEMP% with long file name
    12	w_temp=$($u_psexe 'Write-Host (Get-Item -LiteralPath $Env:TEMP).FullName' < /dev/null | sed -e 's/\r$//')
    13	u_temp=$(wslpath -a -u "$w_temp")
    14	m_temp=$(wslpath -a -m "$u_temp")
    15	
    16	# Execute $runfile as admin
    17	cd "$u_temp"
    18	case "$runfile" in
    19	*.bat)
    20	    $u_psexe -NoProfile Start-Process -Wait -Verb RunAs -WorkingDirectory "$m_temp" -FilePath "$m_cmdexe" -ArgumentList "'/C $m_temp/$runfile'" < /dev/null
    21	    ;;
    22	*.ps1)
    23	    $u_psexe -NoProfile Start-Process -Wait -Verb RunAs -WorkingDirectory "$m_temp" -FilePath "$m_psexe" -ArgumentList "'-NoProfile -ExecutionPolicy RemoteSigned -File $m_temp/$runfile'" < /dev/null
    24	    ;;
    25	esac

コマンド説明

wslpath

バッドノウハウの前に、6, 9, 13, 14 行目で使われている wslpath コマンドについて簡単に説明します。WSL でディストリビューションをインストールすると自動的に作成されるようです。実態は以下のように /init へのシンボリックリンクです。

$ ls -l $(which -a wslpath)
lrwxrwxrwx 1 root root 5 Nov 19 15:28 /bin/wslpath -> /init
lrwxrwxrwx 1 root root 5 Nov 19 15:28 /usr/bin/wslpath -> /init

wslpath を引数なしで起動すると使用例が表示されます。Windows のパス表記を UNIX 系の表記に変換したり、その逆をしたりする機能があります。下表に示すようなパス表記の変換ができます。

$ wslpath
wslpath: Invalid argument
Usage:
    -a    force result to absolute path format
    -u    translate from a Windows path to a WSL path (default)
    -w    translate from a WSL path to a Windows path
    -m    translate from a WSL path to a Windows path, with '/' instead of '\'

EX: wslpath 'c:\users'
オプション指定 出力例
-u /mnt/c/Windows/System32
-w C:\Windows\System32
-m C:/Windows/System32

今回作成したシェルスクリプトでは、パス名を含むシェル変数にどの形式のパス名が設定されているかを示すため、u_, w_, m_ のプリフィクスをつけてあります。

バッドノウハウ

(その 1)   3 行目

cd /mnt/c
cmd.exe などは WSL 側のパスを理解できないようです。WSL から cmd.exe を起動すると、以下のようなメッセージが表示されます。一旦 、C ドライブ直下などに避難して回避します。

'\\wsl.localhost\Ubuntu-24.04\home\username’
上記の現在のディレクトリで CMD.EXE を開始しました。
UNC パスはサポートされません。Windows ディレクトリを既定で使用します。

 

(その 2)   11 行目

環境変数 TEMP のパス名がショートパス名になっている場合があります。ショートパス名は wslpath では扱えないようです、あらかじめここでロングパス名に展開します。

 

(その 3)   12, 20, 23 行目

Windows 側のコマンドを実行すると、なぜか標準入力が吸い取られます。この問題に関連する記事がこちらにあります。< /dev/null によるリダイレクトはその対策です。この記事の説明がシンプル過ぎるので、わかりやすそうな例を示します。

cat file.txt | while read line; doecho line=$line
    なんとか.exe
    …
done

このようなシェルスクリプトの場合、file.txt に複数行あったとしても、なんとか.exe が起動する際に、標準入力が全部吸い込まれてしまうため、ループは 1 回で終了してしまいます。line=... は file.txt の 1 行目だけが表示されます。

今回作成したシェルスクリプトをコマンド行から起動しているだけならば気がつかないかもしれません。このシェルスクリプトを別のシェルスクリプトに組み込んだ場合などで、実行時に標準入力が読み込み可能な状態だと、上記の問題が発生します。

  1. Sudo for WSL (wsl-sudo) / 以下「What is this?」より抜粋
    This tool allows you to run applications in windows elevated user mode from a non-elevated wsl shell. It has full terminal support, so you can run interactive applications like vim or a shell through it.

  2. UAC による権限の昇格が発生すると、ダイアログ・ウインドウが表示されます。これは手動で入力、もしくは、クリックして通過してください。スクリプトにより自動的に指定されたバッチファイルを起動しますが、無人で利用可能というわけではありません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?