pi-shell


Namepi-shell JSON
Version 1.0.7 PyPI version JSON
download
home_pageNone
SummaryA CLI tool for managing multiple Raspberry Pi devices over SSH
upload_time2025-10-26 08:42:27
maintainerNone
docs_urlNone
authorNone
requires_python>=3.6
licenseMIT
keywords raspberry-pi ssh remote management cli iot
VCS
bugtrack_url
requirements paramiko PyYAML cryptography
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Pi Shell - Enhanced Raspberry Pi Management Tool

A CLI tool for managing multiple Raspberry Pi devices over SSH with automatic Pi detection through symlinks. But why does this exist [BHB.bzz](https://bhb.buzz/pi-shell.html)?

## 📦 Installation

### Recommended: Install from PyPI

```bash
pip install pi-shell
```

### Alternative: Install from Source

```bash
# Clone the repository
git clone https://github.com/mcyork/pi-shell.git
cd pi-shell

# Install using pip
pip install .

# Or install in editable mode for development
pip install -e .
```

This automatically installs all dependencies:
- `paramiko` - SSH library for Python
- `PyYAML` - YAML configuration file parser
- `cryptography` - For SSH key generation

After installation, the `pi-shell` command will be available globally.

## 🚀 Quick Start

### Option 1: SSH Key Authentication (Recommended)

1.  **Configure a Pi with automatic key setup:**
    ```bash
    pi-shell add pi1 --host 192.168.1.10 --user pi --password raspberry --push-key
    ```
    This will:
    - Generate an SSH key pair at `~/.ssh/pi-shell` (if it doesn't exist)
    - Push the public key to the Pi for password-less authentication
    - Save the configuration to `~/.config/pi-shell/config.yml` with the key path
    
    **Benefits:** No passwords stored in config, more secure, no password prompts!

### Option 2: Password Authentication

1.  **Configure a Pi with password:**
    ```bash
    pi-shell add pi1 --host 192.168.1.10 --user pi --password raspberry
    ```
    This saves the Pi configuration to `~/.config/pi-shell/config.yml`.
    
    **Note:** Password will be stored in plain text in the config file.

2.  **Check its status:**
    ```bash
    pi-shell status pi1
    ```

3.  **Run a command:**
    ```bash
    # Using the --pi flag
    pi-shell run "uname -a" --pi pi1
    
    # Or if pi1 is set as default
    pi-shell run "uname -a"
    ```

## 🔧 Available Commands

The tool is organized into sub-commands for different actions.

### Core Actions (`run`, `read`, `write`)

These commands perform actions on a target Pi.

-   `run <command>`: Execute a shell command.
-   `run-stream <command>`: Stream output from a long-running command.
-   `read <remote_path>`: Read a file from the Pi.
-   `write <remote_path> <content>`: Write content to a file.

**Example:**
```bash
# Reboot pi2
./pi2 run "sudo reboot"

# Read the hostname from the default pi
./pi-shell read "/etc/hostname"
```

### Management Actions (`add`, `remove`, `list`, `status`, `set-default`)

These commands help you manage your list of Pis.

-   `add <name> --host <host> --user <user> --password <password> [--push-key]`: Add a new Pi. Creates a symlink.
    - Use `--push-key` to automatically set up SSH key authentication (recommended - password used once to push key, then not stored)
    - Without `--push-key`, password is stored in config for ongoing authentication (less secure)
-   `remove <name>`: Remove a Pi. Deletes the symlink.
-   `list`: Show all configured Pis in a table.
-   `set-default <name>`: Set the default Pi for commands.
-   `status [name]`: Check connectivity and get the hostname for one or all Pis.

**Example:**
```bash
# See all configured Pis
./pi-shell list

# Check if all Pis are online
./pi-shell status

# Add a new Pi named 'pi-hole' with SSH key authentication (recommended)
./pi-shell add pi-hole --host 192.168.1.20 --user admin --password raspberry --push-key

# Or add with password authentication only
./pi-shell add pi-hole --host 192.168.1.20 --user admin --password raspberry

# Set it as the default
./pi-shell set-default pi-hole
```

## ⚙️ Configuration

Device details are stored in `~/.config/pi-shell/config.yml` (per-user). While you can edit it manually, it's recommended to use the `add` and `remove` commands.

**Note:** 
- Each user has their own config in their home directory (`~/.config/pi-shell/config.yml`)
- This works with system-wide installations - no conflicts between users!
- You can mix and match authentication methods - some Pis can use SSH keys while others use passwords

### Example:
```yaml
pi1:
  host: 192.168.1.10
  user: pi
  key: ~/.ssh/pi-shell  # SSH key authentication (recommended)
pi2:
  host: 192.168.1.20
  user: pi
  password: raspberry  # Password authentication
default: pi1
```

## 🔑 SSH Key Authentication

The tool can automatically set up SSH key-based authentication, which is more secure and convenient than passwords.

### How It Works:
1. When you use `--push-key` with the `add` command, the tool:
   - Generates an ED25519 SSH key pair at `~/.ssh/pi-shell` (if it doesn't exist)
   - Connects to the Pi using the provided password (one time only)
   - Copies the public key to the Pi's `~/.ssh/authorized_keys`
   - Saves the key path in `config.yml`

2. All future connections use the SSH key automatically - no password needed!

### Benefits:
- ✅ **More Secure:** No passwords stored in plain text
- ✅ **Convenient:** No password prompts during operations
- ✅ **One Key for All:** Same key can be used for all your Pis
- ✅ **LLM-Friendly:** No interactive password prompts when used by AI assistants

### Manual Key Setup:
If you prefer to use your own SSH key:
```bash
./pi-shell add pi1 --host 192.168.1.10 --user pi --key ~/.ssh/id_rsa
```

## 🎯 How It Works

The tool determines which Pi to connect to in the following order of priority:
1.  The `--pi <name>` command-line argument.
2.  The name of the symlink used to execute the script (e.g., `./pi1`).
3.  The `default` entry in `config.yml`.

## 🆘 Troubleshooting

-   **Connection Errors:** Use `./pi-shell status` to check connectivity. Ensure the host IP is correct and the device is on the network.
-   **Host Key Errors:** If you see a "BadHostKeyException", it means the Pi's SSH key has changed (e.g., after an OS reinstall). The tool will provide you with the correct `ssh-keygen -R <host>` command to run to fix it.
-   **Authentication Errors:** If you don't store a password in the config, the tool will prompt you for one. For non-interactive use, consider setting up SSH key-based authentication and providing the key path in `config.yml`.

## 📋 Requirements

-   Python 3.6+
-   paramiko (SSH library)
-   PyYAML
-   SSH access to your Raspberry Pis

## ⚠️ Things to Consider

**Password Security:**
- Passwords stored in `config.yml` are **not encrypted**. They are saved in plain text.
- This tool is designed for development environments with Raspberry Pis, typically using default passwords like "raspberry".
- If you plan to use this tool with production Linux machines or systems with sensitive credentials, be aware that there is no encryption on the YAML configuration file.
- For better security in production environments, consider using SSH key-based authentication instead (use the `--key` parameter when adding a Pi).

## 🗑️ Uninstalling

To uninstall pi-shell:

```bash
pip uninstall pi-shell
```

**Note:** This removes the command but preserves your data:
- Config: `~/.config/pi-shell/config.yml`
- SSH keys: `~/.ssh/pi-shell`
- Symlinks: `/usr/local/bin/keybird`, etc.

For complete removal instructions, see [docs/UNINSTALL.md](docs/UNINSTALL.md)

## 🤖 AI Disclosure

AI was used to help write this code, specifically the tool [Cursor](https://cursor.com), which assisted with development, documentation, and code organization.


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "pi-shell",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": null,
    "keywords": "raspberry-pi, ssh, remote, management, cli, iot",
    "author": null,
    "author_email": "Ian McCutcheon <your.email@example.com>",
    "download_url": "https://files.pythonhosted.org/packages/c5/87/9705d98362a63b8febb3185878fafd34eccf8a89c78a71beead440bfbf88/pi_shell-1.0.7.tar.gz",
    "platform": null,
    "description": "# Pi Shell - Enhanced Raspberry Pi Management Tool\n\nA CLI tool for managing multiple Raspberry Pi devices over SSH with automatic Pi detection through symlinks. But why does this exist [BHB.bzz](https://bhb.buzz/pi-shell.html)?\n\n## \ud83d\udce6 Installation\n\n### Recommended: Install from PyPI\n\n```bash\npip install pi-shell\n```\n\n### Alternative: Install from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/mcyork/pi-shell.git\ncd pi-shell\n\n# Install using pip\npip install .\n\n# Or install in editable mode for development\npip install -e .\n```\n\nThis automatically installs all dependencies:\n- `paramiko` - SSH library for Python\n- `PyYAML` - YAML configuration file parser\n- `cryptography` - For SSH key generation\n\nAfter installation, the `pi-shell` command will be available globally.\n\n## \ud83d\ude80 Quick Start\n\n### Option 1: SSH Key Authentication (Recommended)\n\n1.  **Configure a Pi with automatic key setup:**\n    ```bash\n    pi-shell add pi1 --host 192.168.1.10 --user pi --password raspberry --push-key\n    ```\n    This will:\n    - Generate an SSH key pair at `~/.ssh/pi-shell` (if it doesn't exist)\n    - Push the public key to the Pi for password-less authentication\n    - Save the configuration to `~/.config/pi-shell/config.yml` with the key path\n    \n    **Benefits:** No passwords stored in config, more secure, no password prompts!\n\n### Option 2: Password Authentication\n\n1.  **Configure a Pi with password:**\n    ```bash\n    pi-shell add pi1 --host 192.168.1.10 --user pi --password raspberry\n    ```\n    This saves the Pi configuration to `~/.config/pi-shell/config.yml`.\n    \n    **Note:** Password will be stored in plain text in the config file.\n\n2.  **Check its status:**\n    ```bash\n    pi-shell status pi1\n    ```\n\n3.  **Run a command:**\n    ```bash\n    # Using the --pi flag\n    pi-shell run \"uname -a\" --pi pi1\n    \n    # Or if pi1 is set as default\n    pi-shell run \"uname -a\"\n    ```\n\n## \ud83d\udd27 Available Commands\n\nThe tool is organized into sub-commands for different actions.\n\n### Core Actions (`run`, `read`, `write`)\n\nThese commands perform actions on a target Pi.\n\n-   `run <command>`: Execute a shell command.\n-   `run-stream <command>`: Stream output from a long-running command.\n-   `read <remote_path>`: Read a file from the Pi.\n-   `write <remote_path> <content>`: Write content to a file.\n\n**Example:**\n```bash\n# Reboot pi2\n./pi2 run \"sudo reboot\"\n\n# Read the hostname from the default pi\n./pi-shell read \"/etc/hostname\"\n```\n\n### Management Actions (`add`, `remove`, `list`, `status`, `set-default`)\n\nThese commands help you manage your list of Pis.\n\n-   `add <name> --host <host> --user <user> --password <password> [--push-key]`: Add a new Pi. Creates a symlink.\n    - Use `--push-key` to automatically set up SSH key authentication (recommended - password used once to push key, then not stored)\n    - Without `--push-key`, password is stored in config for ongoing authentication (less secure)\n-   `remove <name>`: Remove a Pi. Deletes the symlink.\n-   `list`: Show all configured Pis in a table.\n-   `set-default <name>`: Set the default Pi for commands.\n-   `status [name]`: Check connectivity and get the hostname for one or all Pis.\n\n**Example:**\n```bash\n# See all configured Pis\n./pi-shell list\n\n# Check if all Pis are online\n./pi-shell status\n\n# Add a new Pi named 'pi-hole' with SSH key authentication (recommended)\n./pi-shell add pi-hole --host 192.168.1.20 --user admin --password raspberry --push-key\n\n# Or add with password authentication only\n./pi-shell add pi-hole --host 192.168.1.20 --user admin --password raspberry\n\n# Set it as the default\n./pi-shell set-default pi-hole\n```\n\n## \u2699\ufe0f Configuration\n\nDevice details are stored in `~/.config/pi-shell/config.yml` (per-user). While you can edit it manually, it's recommended to use the `add` and `remove` commands.\n\n**Note:** \n- Each user has their own config in their home directory (`~/.config/pi-shell/config.yml`)\n- This works with system-wide installations - no conflicts between users!\n- You can mix and match authentication methods - some Pis can use SSH keys while others use passwords\n\n### Example:\n```yaml\npi1:\n  host: 192.168.1.10\n  user: pi\n  key: ~/.ssh/pi-shell  # SSH key authentication (recommended)\npi2:\n  host: 192.168.1.20\n  user: pi\n  password: raspberry  # Password authentication\ndefault: pi1\n```\n\n## \ud83d\udd11 SSH Key Authentication\n\nThe tool can automatically set up SSH key-based authentication, which is more secure and convenient than passwords.\n\n### How It Works:\n1. When you use `--push-key` with the `add` command, the tool:\n   - Generates an ED25519 SSH key pair at `~/.ssh/pi-shell` (if it doesn't exist)\n   - Connects to the Pi using the provided password (one time only)\n   - Copies the public key to the Pi's `~/.ssh/authorized_keys`\n   - Saves the key path in `config.yml`\n\n2. All future connections use the SSH key automatically - no password needed!\n\n### Benefits:\n- \u2705 **More Secure:** No passwords stored in plain text\n- \u2705 **Convenient:** No password prompts during operations\n- \u2705 **One Key for All:** Same key can be used for all your Pis\n- \u2705 **LLM-Friendly:** No interactive password prompts when used by AI assistants\n\n### Manual Key Setup:\nIf you prefer to use your own SSH key:\n```bash\n./pi-shell add pi1 --host 192.168.1.10 --user pi --key ~/.ssh/id_rsa\n```\n\n## \ud83c\udfaf How It Works\n\nThe tool determines which Pi to connect to in the following order of priority:\n1.  The `--pi <name>` command-line argument.\n2.  The name of the symlink used to execute the script (e.g., `./pi1`).\n3.  The `default` entry in `config.yml`.\n\n## \ud83c\udd98 Troubleshooting\n\n-   **Connection Errors:** Use `./pi-shell status` to check connectivity. Ensure the host IP is correct and the device is on the network.\n-   **Host Key Errors:** If you see a \"BadHostKeyException\", it means the Pi's SSH key has changed (e.g., after an OS reinstall). The tool will provide you with the correct `ssh-keygen -R <host>` command to run to fix it.\n-   **Authentication Errors:** If you don't store a password in the config, the tool will prompt you for one. For non-interactive use, consider setting up SSH key-based authentication and providing the key path in `config.yml`.\n\n## \ud83d\udccb Requirements\n\n-   Python 3.6+\n-   paramiko (SSH library)\n-   PyYAML\n-   SSH access to your Raspberry Pis\n\n## \u26a0\ufe0f Things to Consider\n\n**Password Security:**\n- Passwords stored in `config.yml` are **not encrypted**. They are saved in plain text.\n- This tool is designed for development environments with Raspberry Pis, typically using default passwords like \"raspberry\".\n- If you plan to use this tool with production Linux machines or systems with sensitive credentials, be aware that there is no encryption on the YAML configuration file.\n- For better security in production environments, consider using SSH key-based authentication instead (use the `--key` parameter when adding a Pi).\n\n## \ud83d\uddd1\ufe0f Uninstalling\n\nTo uninstall pi-shell:\n\n```bash\npip uninstall pi-shell\n```\n\n**Note:** This removes the command but preserves your data:\n- Config: `~/.config/pi-shell/config.yml`\n- SSH keys: `~/.ssh/pi-shell`\n- Symlinks: `/usr/local/bin/keybird`, etc.\n\nFor complete removal instructions, see [docs/UNINSTALL.md](docs/UNINSTALL.md)\n\n## \ud83e\udd16 AI Disclosure\n\nAI was used to help write this code, specifically the tool [Cursor](https://cursor.com), which assisted with development, documentation, and code organization.\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A CLI tool for managing multiple Raspberry Pi devices over SSH",
    "version": "1.0.7",
    "project_urls": {
        "Homepage": "https://github.com/mcyork/pi-shell",
        "Issues": "https://github.com/mcyork/pi-shell/issues",
        "Repository": "https://github.com/mcyork/pi-shell"
    },
    "split_keywords": [
        "raspberry-pi",
        " ssh",
        " remote",
        " management",
        " cli",
        " iot"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a1053fac734a1491e87ac1c5d5a98f3685275ce602a7a4cc112f8fae72b3db9e",
                "md5": "42e5b4e8a9a0be8586204fc3754a21af",
                "sha256": "3286a85b1b9aa912a7cb5dd4e1e3c05537f38bf46c32ca0b08c46c81dc076302"
            },
            "downloads": -1,
            "filename": "pi_shell-1.0.7-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "42e5b4e8a9a0be8586204fc3754a21af",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 12820,
            "upload_time": "2025-10-26T08:42:26",
            "upload_time_iso_8601": "2025-10-26T08:42:26.428700Z",
            "url": "https://files.pythonhosted.org/packages/a1/05/3fac734a1491e87ac1c5d5a98f3685275ce602a7a4cc112f8fae72b3db9e/pi_shell-1.0.7-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c5879705d98362a63b8febb3185878fafd34eccf8a89c78a71beead440bfbf88",
                "md5": "217fef1dbb90d1b2853bc9b9cc99cf17",
                "sha256": "2767e287f1f17d8fbf73246bc8bccb941f8bf75380da5f7d41a3639ce9846666"
            },
            "downloads": -1,
            "filename": "pi_shell-1.0.7.tar.gz",
            "has_sig": false,
            "md5_digest": "217fef1dbb90d1b2853bc9b9cc99cf17",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 22751,
            "upload_time": "2025-10-26T08:42:27",
            "upload_time_iso_8601": "2025-10-26T08:42:27.309223Z",
            "url": "https://files.pythonhosted.org/packages/c5/87/9705d98362a63b8febb3185878fafd34eccf8a89c78a71beead440bfbf88/pi_shell-1.0.7.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-26 08:42:27",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mcyork",
    "github_project": "pi-shell",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "paramiko",
            "specs": []
        },
        {
            "name": "PyYAML",
            "specs": []
        },
        {
            "name": "cryptography",
            "specs": []
        }
    ],
    "lcname": "pi-shell"
}
        
Elapsed time: 0.94536s