Repository: flutter
Issue: `flutter version` to not crash when it fails to write to stdout
Labels: tool,a: quality,c: proposal,P3,team-tool,triaged-tool

## Use case

I am using `flutter version` in a shell script to get the version number of the installed Flutter SDK.

```
$ flutter --version
Flutter 2.8.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 77d935af4d (3 months ago) • 2021-12-16 08:37:33 -0800
Engine • revision 890a5fca2e
Tools • Dart 2.15.1
```

The shell script needs the version number from the first line, so it pipes the output through `head -n 1`.  The `head` program reads the specified number of lines and then closes stdin.  The `flutter` command then fails to print out the subsequent lines and throws an exception.  The `flutter` process exits with non-zero status and the shell interpreter fails the entire pipeline.

There is actually a race.  Sometimes `flutter version` prints the exception to stderr but still exits with success.

The script is part of a Heroku build extension that allows running Dart programs on Heroku:
<https://github.com/leonhard-llc/heroku-buildpack-flutter-cli>
When `flutter version` fails, the script assumes that the Flutter SDK is not installed and downloads it again.  This makes our deployment times longer.  It also makes them dependent on the Flutter SDK download availability.

<details>

<summary>Output of `heroku-buildpack-flutter-cli` failing to detect the currently installed Flutter SDK, because `flutter version` crashed, and downloading the SDK again</summary>

```
...
remote: -----> Dart app detected
remote: ----->  heroku-buildpack-flutter-cli Starting.
remote: Unhandled exception:
remote: FileSystemException: writeFrom failed, path = '' (OS Error: Broken pipe, errno = 32)
remote: #0      _RandomAccessFile.writeFromSync (dart:io/file_impl.dart:873:7)
remote: #1      _StdConsumer.addStream.<anonymous closure> (dart:io/stdio.dart:286:15)
remote: #2      _rootRunUnary (dart:async/zone.dart:1442:13)
remote: #3      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
remote: #4      _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
remote: #5      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
remote: #6      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
remote: #7      _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
remote: #8      _StreamController._add (dart:async/stream_controller.dart:648:7)
remote: #9      _StreamController.add (dart:async/stream_controller.dart:596:5)
remote: #10     _StreamSinkImpl.add (dart:io/io_sink.dart:136:17)
remote: #11     _IOSinkImpl.write (dart:io/io_sink.dart:269:5)
remote: #12     _StdSink.write (dart:io/stdio.dart:315:11)
remote: #13     Stdio._stdioWrite.<anonymous closure> (package:flutter_tools/src/base/io.dart:359:12)
remote: #14     Stdio._stdioWrite.<anonymous closure> (package:flutter_tools/src/base/io.dart:358:22)
remote: #15     asyncGuard.<anonymous closure> (package:flutter_tools/src/base/async_guard.dart:111:32)
remote: #16     asyncGuard.<anonymous closure> (package:flutter_tools/src/base/async_guard.dart:109:18)
remote: #17     _rootRun (dart:async/zone.dart:1426:13)
remote: #18     _CustomZone.run (dart:async/zone.dart:1328:19)
remote: #19     _runZoned (dart:async/zone.dart:1861:10)
remote: #20     runZonedGuarded (dart:async/zone.dart:1849:12)
remote: #21     runZoned (dart:async/zone.dart:1780:12)
remote: #22     asyncGuard (package:flutter_tools/src/base/async_guard.dart:109:3)
remote: #23     Stdio._stdioWrite (package:flutter_tools/src/base/io.dart:358:5)
remote: #24     Stdio.stdoutWrite (package:flutter_tools/src/base/io.dart:344:7)
remote: #25     StdoutLogger.writeToStdOut (package:flutter_tools/src/base/logger.dart:532:48)
remote: #26     StdoutLogger.printStatus (package:flutter_tools/src/base/logger.dart:512:5)
remote: #27     printStatus (package:flutter_tools/src/globals.dart:197:10)
remote: #28     FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:274:19)
remote: <asynchronous suspension>
remote: #29     AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
remote: <asynchronous suspension>
remote: #30     FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:229:5)
remote: <asynchronous suspension>
remote: #31     run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:62:9)
remote: <asynchronous suspension>
remote: #32     AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
remote: <asynchronous suspension>
remote: #33     main (package:flutter_tools/executable.dart:94:3)
remote: <asynchronous suspension>
remote: ----->  Downloading https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_2.10.2-stable.tar.xz
remote:   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
remote:                                  Dload  Upload   Total   Spent    Left  Speed
remote: 100  591M  100  591M    0     0   287M      0  0:00:02  0:00:02 --:--:--  287M
remote: ----->  Checking that the SHA-256 digest is 03de160d1c30730a248cb5e168ec2de60f883d7e365e6cf57b27786e85436c0f
remote: /tmp/codon/tmp/cache/flutter.tar.xz: OK
remote: ----->  Extracting.
...
```

</details>

The error occurs on Linux, but not on macOS.

## Proposal

Make `flutter version` behave like every other program and silently ignore errors writing to stdout.