---
tags:
  - macOS
  - Tahoe
  - zsh
  - scripting
  - automation
title: Scripting with Zsh on macOS Tahoe
---

# Scripting with Zsh on macOS Tahoe

While the [Getting Started with macOS Tahoe](macOS.md) guide introduces a basic script, Zsh offers a robust set of features for complex automation. This guide dives deeper into the syntax and capabilities of Zsh scripting.

## The Shebang

Every Zsh script on macOS Tahoe should start with the "shebang" line. This tells the system which interpreter to use.

```zsh
#!/bin/zsh
```

## Variables

Variables in Zsh do not require data type declarations.

```zsh
#!/bin/zsh

# String variable
OS_NAME="macOS Tahoe"

# Integer variable
VERSION=26

echo "Running on $OS_NAME version $VERSION"
```

## Conditionals

Zsh uses `[[ ... ]]` for conditional tests, which is more powerful and safer than the older `[ ... ]` syntax found in generic sh.

```zsh
#!/bin/zsh

FILE="config.txt"

if [[ -f "$FILE" ]]; then
    echo "$FILE exists."
else
    echo "$FILE does not exist. Creating it..."
    touch "$FILE"
fi
```

### Common Test Operators

*   `-f`: File exists and is a regular file.
*   `-d`: Directory exists.
*   `-z`: String is empty.
*   `-n`: String is not empty.

## Loops

Automate repetitive tasks using loops.

### For Loop

Iterate over a list of items or files.

```zsh
#!/bin/zsh

# Rename all .txt files to .md
for file in *.txt; do
    mv "$file" "${file%.txt}.md"
done
```

## Handling Arguments

Scripts can accept input from the command line.

*   `$1`, `$2`, etc.: Positional arguments.
*   `$#`: Number of arguments passed.
*   `$@`: All arguments as a list.

```zsh
#!/bin/zsh

if [[ $# -eq 0 ]]; then
    echo "Usage: $0 <name>"
    exit 1
fi

echo "Hello, $1!"
```

## User Input

You can pause the script to ask for user input using `read`.

```zsh
#!/bin/zsh

read "response?Do you want to continue? (y/n) "

if [[ "$response" =~ ^[Yy]$ ]]; then
    echo "Continuing..."
else
    echo "Aborting."
    exit 0
fi
```