下記記事を書く際にwslコマンドの-e, --exec
オプションを知り、曖昧な理解しかできなかったため改めて調べたことを備忘録として残します。
1.シェルを経由する場合の実行までのパイプラインについて
# パイプラインのイメージ
wsl grep sample.txt *.log # ①入力受付
↓
wsl /usr/bin/grep sample.txt aaa.log bbb.log ccc.log # ②字句解析(変数展開)
↓
argv = ["grep", "sample.txt", "aaa.log", "bbb.log", "ccc.log"] # ②字句解析(argv[]配列を作成)
↓
execve(argv[0], argv, environ) # ③プログラム起動
ステップ | 担当 | 処理内容 |
---|---|---|
①入力受付 | シェル | 文字列を丸ごと受け取る |
②字句解析 | シェル | 変数展開 $HOME, ワイルドカード *.log, 引用符処理 "foo bar" などを解釈し、argv[]配列(=単語リスト)を作る |
③プログラム起動 | カーネル | execve() で /usr/bin/grep をメモリに読み込み、argv[0]〜を渡してスタート |
※ execve()とはLinux/UNIX 系OSが提供するシステムコールの1つです。詳しくは以下の記事など。
https://progzakki.sanachan.com/program-lang/c/how-to-use-execve/
2.wsl <cmd>
とwsl -e <cmd>
の差
実行方法 | argv[]作成担当 | シェル機能(変数展開・ワイルドカード) |
---|---|---|
wsl <cmd> |
bash | あり |
wsl -e <cmd> |
wsl.exe(Windows 側) | なし(空白・引用符だけ最小限処理) |
2.1.具体例
ワイルドカードの展開
# bash経由(シェルが*.logを展開)
PS> wsl grep *.log
argv = ["grep", "aaa.log", "bbb.log", ...]
# -e で直接実行(*.log がそのまま渡る)
PS> wsl -e grep *.log
argv = ["grep", "*.log"] # ← 文字列のまま
変数展開
CMD> wsl echo $HOME
/home/ubuntu
CMD> wsl -e echo $HOME
$HOME