---
title: "Make command-line tools read the locale or · Agent Wranglers"
url: https://agentwranglers.se/playbook/localization/apps-and-command-line-tools/cli-locale
id: LOC-39
level: Recommended
updated: 2026-10-22
tokens: 827
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Make command-line tools read the locale or say they do not

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Apps and command-line tools](https://agentwranglers.se/playbook/localization/apps-and-command-line-tools.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-22.

- ID: LOC-39
- Level: Recommended
- Chapter: [Apps and command-line tools](https://agentwranglers.se/playbook/localization/apps-and-command-line-tools.md)
- Rule: A command-line tool that prints translated text picks its language from `LC_ALL`, then `LC_MESSAGES`, then `LANG`. A tool in one language says so in its help. Machine-readable output is the same in every locale.
- Check: Run the tool with `LC_ALL=sv_SE.UTF-8` and with `LC_ALL=C`. Human messages change language, or the help says the tool is English only. The `--json` output is byte for byte equal in both runs.
- How: POSIX sets the order. `LC_ALL` wins, then the category variable such as `LC_MESSAGES` or `LC_NUMERIC`, then `LANG`. Use gettext or your language's equivalent, which reads them for you. Keep JSON and other output for scripts free of translated words and locale number formats, as [Offer JSON output with a stable shape](https://agentwranglers.se/playbook/desktop-apps/command-line-tools/json-output.md) says. A decimal comma from `LC_NUMERIC` breaks every script that parses the output.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### Python example

```python
import gettext
import json
import locale

locale.setlocale(locale.LC_ALL, "")
_ = gettext.translation("example-cli", localedir="locale", fallback=True).gettext
print(_("Found {count} files").format(count=3))
print(json.dumps({"files": 3, "ratio": 0.5}))
```

### Go example

```go
import (
	"encoding/json"
	"os"
)

func messageLocale() string {
	for _, name := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} {
		if value := os.Getenv(name); value != "" {
			return value
		}
	}
	return "C"
}

func printJSON(result any) error { return json.NewEncoder(os.Stdout).Encode(result) }
```

## Sources

- [POSIX Base Definitions (Chapter 8, Environment variables)](https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap08.html)

## Related rules

- DSK-22 [Offer JSON output with a stable shape](https://agentwranglers.se/playbook/desktop-apps/command-line-tools/json-output.md) in Desktop apps, extensions and CLIs

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/localization/apps-and-command-line-tools/cli-locale">Agent Wranglers localization playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Translate the store listing for every language the app ships](https://agentwranglers.se/playbook/localization/apps-and-command-line-tools/localized-store-listings.md)
- [Apps and command-line tools](https://agentwranglers.se/playbook/localization/apps-and-command-line-tools.md)
