MOB-LOG

モブおじの記録 (Programming, 統計・機械学習)

powershellでコマンドのbatが構文エラーを出すとき。

TL;DR

(この記事は実はFlutterは関係ありません)

flutterコマンドが << の使い方が誤っています。が出てきて、Win11のflutterコマンドがおかしくなった。

flutter doctor -v
<< の使い方が誤っています。

結論は、なぜかFLUTTER_PATHの状態がgit merge中になっていて、コンフリクト起こしたファイルを参照していて[ある環境変数]="<<<<< HEAD" を展開したため構文エラーになっていた。git merge --abortで解決した。しょうもな(なぜflutterのmergeしようとしているのか)。

内容自体はどうでもいいけれど、 batファイルのエラー文は情報が少なすぎるので、Get-commandとかでソースコード見たり、@ECHO offコメントアウトして実行してみたり(@ECHO off@REM @ECHO off)すると何かしら情報が得られる。

学び

  • batファイルでよくわからんエラーが出たときは、Get-commandとかでソースコード見たり、@ECHO offコメントアウトして実行してみたり(@ECHO off@REM @ECHO off)すると何かしら情報が得られる。
  • batなどのスクリプトを実行しようとして「<< の使い方が間違っている」というのはmergeでコンフリクト中のファイルを参照して馬鹿になっている可能性がある(mergeで衝突したまま放っておく人類はいないはずだが)。

ここから先は長いのと、実はflutterに関係ない内容なので読まなくてよい

以下詳細、いきさつ (TOO LONG)

起り:flutter doctor -v<< の使い方が誤っています。 が出てきてflutterコマンドが実行できない。

pathは通っている様子。

Get-Command flutter

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     flutter.bat                                        0.0.0.0    C:\src\flutter\bin\flutter.bat

Winの環境変数が参照できなくて(空っぽ)、構文が崩れてしまい、お前<<の使い方知らないのかよ、と言われているような気がする。(昨日InsiderPreviewのアップデートを実行したので、それで環境変数の関係が崩れたのかも)

「<<の使い方云々」とか書いてあるコードを探してみると、C:/src/flutter/bin/flutter.bat 内には<<が現れたりそのエラーが出そうな部分はなし。

C:\src\flutter\bin\flutter.bat
@ECHO off
REM Copyright 2014 The Flutter Authors. All rights reserved.
REM Use of this source code is governed by a BSD-style license that can be
REM found in the LICENSE file.

REM ---------------------------------- NOTE ----------------------------------
REM
REM Please keep the logic in this file consistent with the logic in the
REM `flutter` script in the same directory to ensure that Flutter & Dart continue to
REM work across all platforms!
REM
REM --------------------------------------------------------------------------

SETLOCAL

REM To debug the tool, you can uncomment the following line to enable debug mode:
REM SET FLUTTER_TOOL_ARGS="--enable-asserts %FLUTTER_TOOL_ARGS%"

FOR %%i IN ("%~dp0..") DO SET FLUTTER_ROOT=%%~fi

REM If available, add location of bundled mingit to PATH
SET mingit_path=%FLUTTER_ROOT%\bin\mingit\cmd
IF EXIST "%mingit_path%" SET PATH=%PATH%;%mingit_path%

REM We test if Git is available on the Host as we run git in shared.bat
REM  Test if the flutter directory is a git clone, otherwise git rev-parse HEAD would fail
IF NOT EXIST "%flutter_root%\.git" (
  ECHO Error: The Flutter directory is not a clone of the GitHub project.
  ECHO        The flutter tool requires Git in order to operate properly;
  ECHO        to set up Flutter, run the following command:
  ECHO        git clone -b stable https://github.com/flutter/flutter.git
  EXIT 1
)

REM Include shared scripts in shared.bat
SET shared_bin=%FLUTTER_ROOT%\bin\internal\shared.bat
CALL "%shared_bin%"

SET flutter_tools_dir=%FLUTTER_ROOT%\packages\flutter_tools
SET cache_dir=%FLUTTER_ROOT%\bin\cache
SET snapshot_path=%cache_dir%\flutter_tools.snapshot
SET dart_sdk_path=%cache_dir%\dart-sdk
SET dart=%dart_sdk_path%\bin\dart.exe

SET exit_with_errorlevel=%FLUTTER_ROOT%/bin/internal/exit_with_errorlevel.bat

REM Chaining the call to 'dart' and 'exit' with an ampersand ensures that
REM Windows reads both commands into memory once before executing them. This
REM avoids nasty errors that may otherwise occur when the dart command (e.g. as
REM part of 'flutter upgrade') modifies this batch script while it is executing.
REM
REM Do not use the CALL command in the next line to execute Dart. CALL causes
REM Windows to re-read the line from disk after the CALL command has finished
REM regardless of the ampersand chain.
"%dart%" --disable-dart-dev --packages="%flutter_tools_dir%\.dart_tool\package_config.json" %FLUTTER_TOOL_ARGS% "%snapshot_path%" %* & "%exit_with_errorlevel%"

どこかでおかしくなっているのかわからないので、@ECHO offコメントアウトしてもう一度実行してみることに (→ @REM @ECHO off)。REMとかCALLとか大体の結果が現れるけれど、C:\src\flutter\bin\internal\shared.batでエラーが出ていることが分かった。

>REM Include shared scripts in shared.bat

>SET shared_bin=C:\src\flutter\bin\internal\shared.bat

>CALL "C:\src\flutter\bin\internal\shared.bat"
<< の使い方が誤っています。

C:\src\flutter\bin\internal\shared.bat@ECHO offコメントアウトし、再度実行↓。

> flutter
// 省略
>IF NOT EXIST "C:\src\flutter\bin\cache\engine-dart-sdk.stamp" GOTO do_sdk_update_and_snapshot

>SET /P dart_required_version= 0<"C:\src\flutter\bin\internal\engine.version"

>SET /P dart_installed_version= 0<"C:\src\flutter\bin\cache\engine-dart-sdk.stamp"
<< の使い方が誤っています。

>  IF <<<<<<< HEAD NEQ cdbeda788a293fa29665dc3fa3d6e63bd221cb0d GOTO do_sdk_update_and_snapshot

IF %dart_required_version% NEQ %dart_installed_version% GOTO do_sdk_update_and_snapshot

の部分で、%dart_required_version%<<<<<<< HEAD になっている様子(意味不明)。

%engine_version_path%C:\src\flutter\bin\internal\engine.versionを参照しているようなので、これを除いてみる↓。

Untitled

<<<<<<< HEAD
cdbeda788a293fa29665dc3fa3d6e63bd221cb0d
=======
767d8c75e898091b925519803830fc2721658d07
>>>>>>> 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e

意味不明。なぜvscodeのgit mergeがconflictした時のエディターがここに保存されているのか。C:/src/flutter/ まで行ってgit statusすると、merge中だという(?)。なんか知らんうちにmergeしようとしてる。意味不明なので git merge --abort して終わってもらった。

flutter doctor -v → 成功!

結論、なぜか知らんけどflutterのgitでmergeしようとしていてconflictを解決しようとしているindexの状態で様々なファイルがおかしくなっていて、該当コマンドを実行しようとしていた。という話。(なぜmergeしようとしてたのかは謎)