X Home
Erbauliches Wörterbücher - online Lateinische Verbklassen Griechische Grammatik Griechische Verbklassen dynamisch Griechische Verbformen (breit) Griechische Verbformen (schmal) Griechischer Wortschatz Griechisch-Konverter
AI: MCP-Server AI: Local/Cloud LLMs AI: AI-Scripting Toolbox CSV-Verarbeitung Scanner Toolbox Lexer Eigener Nameserver Cloud-Telefonanlage mit Asterisk Fernsteuerung von Outlook per ssh Interaktive HTML-Tabelle Bilderverwaltung im Browser CSV => Excel (formatiert) Befehlsreferenzen
Horae vulnerant ... Terminal 2.0 ...



Bash · models.txt · OpenCode · OpenRouter · OpenCode Zen · Ollama · OCR · Vision · Summaries

Practical LLM Applications on the Linux Command Line

Small shell scripts are often sufficient to turn a general-purpose LLM into a repeatable Linux tool. The examples on this page cover direct local prompting, provider-independent prompting, OCR, plant recognition and transcript summarization. The deliberately minimal myllmcalllocal talks directly to the Ollama command line and lets the user choose an installed model interactively. The more automated scripts move model choice into ~/models.txt and can delegate inference either to OpenCode with a provider such as OpenRouter, or directly to Ollama. OpenCode Zen and local Ollama models are natural alternatives without changing the basic workflow design.

Bash OpenCode OpenRouter OpenCode Zen Ollama models.txt

Overview: LLMs as Small Unix Tools

The scripts follow the usual Unix division of labour. Bash handles arguments, files, naming, loops, subprocesses and deterministic text processing. The LLM is called only for the semantic part of the task: understanding an image, transcribing a scan, identifying a plant or compressing a transcript. This keeps the surrounding workflow transparent and easy to automate.

Bash script arguments, files, pipes
model choice
interactive or ~/models.txt simple local call or automated configuration
inference
Ollama or OpenCode local or provider-backed LLM

Generic LLM calls

myllmcalllocal is the minimal direct Ollama variant for a task file and interactive model selection. myopencodecall turns opencode run into a provider-independent shell command for a prompt plus an optional text or image file.

OCR and vision

myollamaocr performs local OCR through Ollama, while myopenrouterocr and myopenrouterimagerecognition use OpenCode with a vision-capable provider model.

Transcript processing

myyoutubesubs downloads and cleans YouTube subtitles; myyoutubesubs_local extracts subtitles from local MP4 files. Both can optionally ask an LLM for a condensed version.

1

myllmcalllocal: The Simplest Direct Local LLM Call

A minimal Bash wrapper around the local ollama command.

myllmcalllocal demonstrates the shortest path from a text file to a locally installed language model. It accepts exactly one task file, verifies that the ollama command exists, obtains the locally available model names from ollama list, and presents them through Bash's built-in select menu. The selected model then receives the complete file content on standard input. The model response is written to result.txt.

Interface

Usage: myllmcalllocal [-h] <task>.txt

The task itself is simply a text file. There is no provider configuration, API key, model option or OpenCode dependency. The only runtime prerequisite is a working local Ollama installation with at least one downloaded model.

Design characteristic

Model selection is intentionally interactive rather than configuration-driven. This makes the script well suited for manual experiments and illustrates the local inference mechanism without an additional abstraction layer. For unattended or repeatable workflows, the later scripts replace this interaction with ~/models.txt.

Essential excerpt · discover and select a local model

models=$(ollama list | awk -F' ' '{print $1}')
options=($models)

PS3="Please select a model: "
select model in "${options[@]}"; do
    if [[ -n $model ]]; then
        break
    fi
    echo "Invalid option. Please select a valid model."
done

Essential excerpt · invoke Ollama through a Unix pipe

cat "$1" | ollama run "$model" > result.txt

Local workflow

task.txt myllmcalllocal ollama list interactive model choice ollama run result.txt
2

Central Model Selection with ~/models.txt

Model choice is configuration, not a command-line option.

Each script derives its own name from $0 and searches ~/models.txt for a line beginning with that name followed by a colon. If no script-specific entry exists, the line default: is used. The user can therefore switch models globally or per application without modifying the scripts and without adding a model-selection option to every command line.

Example configuration

default:openrouter/deepseek/deepseek-v4-flash-0731
myopencodecall:openrouter/deepseek/deepseek-v4-flash-0731
myopenrouterimagerecognition:openrouter/qwen/qwen3-vl-8b-instruct
myopenrouterocr:openrouter/qwen/qwen3-vl-8b-instruct
myyoutubesubs_local:openrouter/deepseek/deepseek-v4-flash-0731
myyoutubesubs:openrouter/deepseek/deepseek-v4-flash-0731
myollamaocr:glm-ocr

Lookup policy

  1. Require $HOME/models.txt.
  2. Look for <script-name>:<model>.
  3. If absent, look for default:<model>.
  4. If neither exists, terminate with an explicit error.

For OpenCode calls, model identifiers use OpenCode's provider/model notation. The local myollamaocr script is the deliberate exception because it talks directly to Ollama and therefore uses Ollama's own model name such as glm-ocr.

Essential excerpt · common load_model()

MODELS_FILE="$HOME/models.txt"
MODEL=""

load_model()
{
    local script_name=${0##*/}

    [ -f "$MODELS_FILE" ] || {
        echo "Fehler: Modelldatei '$MODELS_FILE' nicht gefunden." >&2
        exit 1
    }

    MODEL=$(awk -v key="$script_name" '
        index($0, key ":") == 1 {
            print substr($0, length(key) + 2)
            exit
        }' "$MODELS_FILE")

    [ -n "$MODEL" ] ||
        MODEL=$(awk '
            index($0, "default:") == 1 {
                print substr($0, 9)
                exit
            }' "$MODELS_FILE")

    [ -n "$MODEL" ] || exit 1
}
3

myopencodecall: Generic Prompt and File Interface

A small wrapper around opencode run for shell scripts and one-shot commands.

myopencodecall is the generic member of the set. The remaining command-line arguments form the prompt. With -f, one text or image file is attached. The model itself is deliberately not selectable on the command line; it is resolved through ~/models.txt and then passed to OpenCode with -m internally.

Essential excerpt · constructing the OpenCode invocation

load_model
prompt="$*"

args=(run -m "$MODEL" "$prompt")

if [ -n "$file" ]; then
    args+=(-f "$file")
fi

opencode "${args[@]}"

Generic call workflow

prompt + optional file myopencodecall ~/models.txt opencode run configured provider
myopencodecall "Explain the difference between fork and exec."
myopencodecall -f notes.txt "Summarize the attached file in five bullet points."
myopencodecall -f scan.png "Describe this image."
4

OCR: Local Ollama or Cloud Vision Model

Two scripts implement the same application with different inference paths.

myollamaocr · local OCR

This script bypasses OpenCode and calls the local Ollama generate API directly. The image is Base64 encoded, inserted into a JSON request with jq, and sent to http://127.0.0.1:11434/api/generate. The recognized text is written beside the image as a .txt file.

base64 -w 0 "$INPUT" > "$IMAGE64"

jq -n \
    --rawfile image "$IMAGE64" \
    --arg model "$MODEL" \
    '{
        model: $model,
        prompt: "Text Recognition:",
        images: [$image],
        stream: false
    }' > "$REQUEST"

curl --data-binary "@$REQUEST" \
     "$OLLAMA_URL"

myopenrouterocr · OCR through OpenCode

Here OpenCode supplies the attachment handling and provider abstraction. The script contributes the task-specific OCR prompt, the input file and the configured model. With the supplied configuration, that model is obtained through OpenRouter.

opencode run \
    -m "$MODEL" \
    'Perform OCR on this scanned document.
     Transcribe all visible text accurately,
     preserve line and paragraph structure where possible,
     and output only the transcription.' \
    -f "$file" \
    > "$out"

Two OCR paths

image myollamaocr Ollama localhost local vision model
image myopenrouterocr OpenCode OpenRouter / alternative provider
5

myopenrouterimagerecognition: Plant Recognition

Vision models can be wrapped just as easily as text models.

This script asks a vision-capable model to identify a plant from an image. It returns the most likely German common name and, where reliable, the scientific name. In single-file mode it creates a matching .txt file. Batch mode scans the current directory for JPEG images and additionally produces recognition.csv.

Essential excerpt · task-specific vision prompt

opencode run \
    -m "$MODEL" \
    'Identify the plant shown in this image.
     Give the most likely German common name first,
     followed by the scientific name in parentheses
     if you can determine it reliably.
     If the identification is uncertain, say so and
     give the most likely alternatives.
     Output only the identification.' \
    -f "$file" \
    > "$out"

Plant-recognition workflow

JPG / JPEG script or batch loop vision model TXT+ recognition.csv

The supplied models.txt assigns the vision-capable openrouter/qwen/qwen3-vl-8b-instruct specifically to this script, independently of the default text model. This is exactly the kind of specialization for which the per-script configuration was introduced.

6

Transcript Processing and Optional LLM Summaries

The deterministic part stays in ordinary command-line tools; OpenCode is added only at the end.

myyoutubesubs · online source

yt-dlp downloads automatic subtitles for a single YouTube URL or a URL list. An AWK stage removes WebVTT headers, timestamps, tags, entities, empty lines and immediately repeated lines. The result becomes a normal text file. With -s, OpenCode summarizes that file.

yt-dlp \
  --write-auto-subs \
  --skip-download \
  "$URL"

# ... VTT cleanup with awk ...

opencode run -m "$MODEL" -f "$file" \
  "Summarize the content of the attached file
   concisely and completely. Output only the summary." \
  > "$tmp"

fold -s -w 80 "$tmp" > "$condensed"

myyoutubesubs_local · local MP4 source

The local counterpart processes all MP4 files in the current directory. ffprobe locates an embedded subtitle stream, preferring the stream marked as default. ffmpeg extracts it as SRT, with WebVTT as fallback. The same cleanup and optional OpenCode summarization then follow.

ffprobe -v error \
  -select_streams s \
  -show_entries stream=index:stream_disposition=default \
  -of csv=p=0 -- "$file"

ffmpeg -v error -y -i "$file" \
  -map "0:${stream_index}" -c:s srt "$srt"

opencode run -m "$MODEL" \
  "Summarize the content ... without translation." \
  -f "$inputfile" \
  > "$tmp"

Transcript-to-summary workflow

YouTube / MP4 yt-dlp or ffprobe/ffmpeg AWK cleanup TXT OpenCode summary *_condensed.txt
7

OpenCode, OpenRouter, OpenCode Zen and Ollama

The scripts separate application logic from the concrete model provider.

OpenRouter

In the supplied setup, most OpenCode-based scripts use model IDs beginning with openrouter/. OpenCode handles the file attachment and request; OpenRouter acts as the hosted model gateway. A single OpenCode installation can therefore use different text and vision models without provider-specific shell code.

OpenCode Zen

OpenCode Zen is an alternative provider integrated into OpenCode. It exposes a curated set of models tested for OpenCode and is configured like other providers. After authentication, a Zen model can be selected with an OpenCode model ID such as opencode/<model>. For these scripts, changing the corresponding entry in ~/models.txt is sufficient; the application code remains the same.

Ollama

Ollama is the local alternative. It can be used directly, as in myollamaocr, or exposed as an OpenCode provider. In the latter case the existing OpenCode-based scripts can keep their opencode run workflow while inference occurs on localhost, provided the local model has the required text or vision capabilities.

Provider abstraction through OpenCode

application script model ID from ~/models.txt OpenCode OpenRouter/ OpenCode Zen/ Ollama

Why keep OpenCode between Bash and the provider?

The shell scripts need only one stable interface: opencode run -m MODEL PROMPT -f FILE. Provider authentication, model discovery and provider-specific communication remain OpenCode's job. This is especially useful for multimodal calls because the Bash code does not need to construct provider-specific JSON payloads or Base64 attachments. The direct Ollama OCR script demonstrates the opposite design when full local control and a minimal HTTP dependency are preferred.

Switching provider without changing the script

# Hosted gateway
myopenrouterocr:openrouter/qwen/qwen3-vl-8b-instruct

# Alternative: OpenCode Zen
myopenrouterocr:opencode/<vision-model>

# Alternative: locally configured Ollama provider in OpenCode
myopenrouterocr:ollama/<vision-model>

Direct Comparison of the Seven Applications

Script Purpose Deterministic tools LLM path Output
myllmcalllocal simple local task-file execution Bash, awk, select, pipe direct Ollama CLI, interactively selected model result.txt
myopencodecall generic prompt + optional file Bash argument handling OpenCode → configured provider stdout
myollamaocr local document OCR base64, jq, curl direct Ollama API basename.txt
myopenrouterocr cloud/provider document OCR Bash file handling OpenCode → OpenRouter by current config basename.txt
myopenrouterimagerecognition plant identification Bash loop + CSV output OpenCode → vision provider TXT + optional CSV
myyoutubesubs YouTube subtitle extraction + summary yt-dlp, awk, fold optional OpenCode summary TXT / condensed TXT
myyoutubesubs_local embedded MP4 subtitles + summary ffprobe, ffmpeg, awk, fold optional OpenCode summary TXT / condensed TXT
Common pattern: keep deterministic processing in shell utilities and put only the semantic step behind an LLM call. The minimal myllmcalllocal variant chooses a local Ollama model interactively; the automated scripts keep model selection in ~/models.txt. OpenCode provides a uniform bridge to hosted or local providers, while direct Ollama access remains useful where a completely local, narrowly controlled call is preferable. The scripts therefore remain small while the model backend can evolve independently.

Official References

  • OpenCode models and provider configuration: opencode.ai/docs/models and opencode.ai/docs/providers
  • OpenCode Zen: opencode.ai/docs/zen
  • OpenRouter provider and model gateway: openrouter.ai
  • Ollama local runtime and API: docs.ollama.com
  • yt-dlp: github.com/yt-dlp/yt-dlp
  • FFmpeg / ffprobe: ffmpeg.org

Legal notice