Co-authored-by: Sam Roberts <158088236+g-samroberts@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
7.0 KiB
Automate tasks with headless mode
Automate tasks with Gemini CLI. Learn how to use headless mode, pipe data into Gemini CLI, automate workflows with shell scripts, and generate structured JSON output for other applications.
Prerequisites
- Gemini CLI installed and authenticated.
- Familiarity with shell scripting (Bash/Zsh).
Why headless mode?
Headless mode runs Gemini CLI once and exits. It's perfect for:
- CI/CD: Analyzing pull requests automatically.
- Batch processing: Summarizing a large number of log files.
- Tool building: Creating your own "AI wrapper" scripts.
How to use headless mode
Run Gemini CLI in headless mode by providing a prompt with the -p (or
--prompt) flag. This bypasses the interactive chat interface and prints the
response to standard output (stdout). Positional arguments without the flag
default to interactive mode, unless the input or output is piped or redirected.
Run a single command:
gemini -p "Write a poem about TypeScript"
How to pipe input to Gemini CLI
Feed data into Gemini using the standard Unix pipe |. Gemini reads the
standard input (stdin) as context and answers your question using standard
output.
Pipe a file:
macOS/Linux
cat error.log | gemini -p "Explain why this failed"
Windows (PowerShell)
Get-Content error.log | gemini -p "Explain why this failed"
Pipe a command:
git diff | gemini -p "Write a commit message for these changes"
Use Gemini CLI output in scripts
Because Gemini prints to stdout, you can chain it with other tools or save the results to a file.
Scenario: Bulk documentation generator
You have a folder of Python scripts and want to generate a README.md for each
one.
-
Save the following code as
generate_docs.sh(orgenerate_docs.ps1for Windows):macOS/Linux (
generate_docs.sh)#!/bin/bash # Loop through all Python files for file in *.py; do echo "Generating docs for $file..." # Ask Gemini CLI to generate the documentation and print it to stdout gemini -p "Generate a Markdown documentation summary for @$file. Print the result to standard output." > "${file%.py}.md" doneWindows PowerShell (
generate_docs.ps1)# Loop through all Python files Get-ChildItem -Filter *.py | ForEach-Object { Write-Host "Generating docs for $($_.Name)..." $newName = $_.Name -replace '\.py$', '.md' # Ask Gemini CLI to generate the documentation and print it to stdout gemini -p "Generate a Markdown documentation summary for @$($_.Name). Print the result to standard output." | Out-File -FilePath $newName -Encoding utf8 } -
Make the script executable and run it in your directory:
macOS/Linux
chmod +x generate_docs.sh ./generate_docs.shWindows (PowerShell)
.\generate_docs.ps1This creates a corresponding Markdown file for every Python file in the folder.
Extract structured JSON data
When writing a script, you often need structured data (JSON) to pass to tools
like jq. To get pure JSON data from the model, combine the
--output-format json flag with jq to parse the response field.
Scenario: Extract and return structured data
-
Save the following script as
generate_json.sh(orgenerate_json.ps1for Windows):macOS/Linux (
generate_json.sh)#!/bin/bash # Ensure we are in a project root if [ ! -f "package.json" ]; then echo "Error: package.json not found." exit 1 fi # Extract data gemini --output-format json "Return a raw JSON object with keys 'version' and 'deps' from @package.json" | jq -r '.response' > data.jsonWindows PowerShell (
generate_json.ps1)# Ensure we are in a project root if (-not (Test-Path "package.json")) { Write-Error "Error: package.json not found." exit 1 } # Extract data (requires jq installed, or you can use ConvertFrom-Json) $output = gemini --output-format json "Return a raw JSON object with keys 'version' and 'deps' from @package.json" | ConvertFrom-Json $output.response | Out-File -FilePath data.json -Encoding utf8 -
Run the script:
macOS/Linux
chmod +x generate_json.sh ./generate_json.shWindows (PowerShell)
.\generate_json.ps1 -
Check
data.json. The file should look like this:{ "version": "1.0.0", "deps": { "react": "^18.2.0" } }
Build your own custom AI tools
Use headless mode to perform custom, automated AI tasks.
Scenario: Create a "Smart Commit" alias
You can add a function to your shell configuration to create a git commit
wrapper that writes the message for you.
macOS/Linux (Bash/Zsh)
-
Open your
.zshrcfile (or.bashrcif you use Bash) in your preferred text editor.nano ~/.zshrcNote: If you use VS Code, you can run
code ~/.zshrc. -
Scroll to the very bottom of the file and paste this code:
function gcommit() { # Get the diff of staged changes diff=$(git diff --staged) if [ -z "$diff" ]; then echo "No staged changes to commit." return 1 fi # Ask Gemini to write the message echo "Generating commit message..." msg=$(echo "$diff" | gemini -p "Write a concise Conventional Commit message for this diff. Output ONLY the message.") # Commit with the generated message git commit -m "$msg" }Save your file and exit.
-
Run this command to make the function available immediately:
source ~/.zshrc
Windows (PowerShell)
-
Open your PowerShell profile in your preferred text editor.
notepad $PROFILE -
Scroll to the very bottom of the file and paste this code:
function gcommit { # Get the diff of staged changes $diff = git diff --staged if (-not $diff) { Write-Host "No staged changes to commit." return } # Ask Gemini to write the message Write-Host "Generating commit message..." $msg = $diff | gemini -p "Write a concise Conventional Commit message for this diff. Output ONLY the message." # Commit with the generated message git commit -m "$msg" }Save your file and exit.
-
Run this command to make the function available immediately:
. $PROFILE -
Use your new command:
gcommitGemini CLI will analyze your staged changes and commit them with a generated message.
Next steps
- Explore the Headless mode reference for full JSON schema details.
- Learn about Shell commands to let the agent run scripts instead of just writing them.