Гид по технологиям

rc — простой и чистый shell из Plan 9

8 min read Linux Обновлено 05 Dec 2025
rc shell: простой shell из Plan 9
rc shell: простой shell из Plan 9

Изображение: оболочка rc — иллюстрация

Содержание

  • Что такое Plan 9?
  • Установка оболочки rc
  • Использование и написание простых скриптов rc
  • Базовые операторы: переменные, файлы, пайпы
  • Управление потоком: условия, циклы, функции
  • Советы, сравнения и когда не использовать rc
  • Частые вопросы

Что такое Plan 9?

Plan 9 — это экспериментальная операционная система, разработанная в Bell Labs как преемник идей UNIX с целью упростить модель операционной системы и сделать её более однородной. Разработка началась в 1980-х годах; после официального завершения активной разработки многие компоненты поддерживаются сообществом. Plan 9 сохранил знакомый набор утилит (cp, mv, rm), но переосмыслил некоторые концепции — например, работу с пространством имён, сетевыми ресурсами и единообразным доступом к ресурсам через файловую модель.

Вид сайта Plan 9 и исторические артефакты

Ключевые идеи Plan 9, полезные для понимания rc как оболочки:

  • Простая и единообразная файловая модель: почти всё представлено как файлы и каталоги.
  • Стремление к ясности интерфейсов и минимальной грамматике.
  • Инструменты разработаны так, чтобы их можно было комбинировать и скриптовать простыми, предсказуемыми способами.

Одна из неклассических составляющих экосистемы — текстовый редактор sam и графический интерфейс acme; многие из утилит доступны в Linux через проект plan9port, который собирает и адаптирует софт Plan 9 для POSIX-сред.

Текстовый редактор sam в Plan 9 и аналогах

Особое внимание в Plan 9 уделяется оболочке rc: она короче и проще по синтаксису, чем традиционные POSIX-оболочки, и её цели — предсказуемость и обучаемость.

Фрагмент man-страницы rc

Установка оболочки rc

Установка rc в Linux обычно выполняется через подключение репозитория plan9port и запуск входящего в него установщика. Ниже — развернутая и адаптированная инструкция.

Важное примечание: команды и пути в примерах предполагают стандартную файловую структуру и относительные права доступа. Меняйте /home/$USER на соответствующую домашнюю директорию в вашей системе.

  1. Склонируйте репозиторий plan9port на локальную машину:
git clone https://github.com/9fans/plan9port.git /home/$USER/plan9port
cd /home/$USER/plan9port
  1. Запустите скрипт установки, который соберёт билдера Plan 9 и далее остальные утилиты:
./INSTALL

Процесс может занять несколько минут в зависимости от мощности машины и наличия зависимостей. На системах с ограниченными ресурсами компиляция может потребовать дополнительного времени.

Компиляция plan9port в терминале

  1. После сборки быстрый запуск утилит возможен из директории bin внутри репозитория:
./bin/acme

Это запустит графический редактор acme (если ваша система поддерживает запуск графики из собранных утилит).

Acme — графический редактор из plan9port

  1. Чтобы использовать утилиты plan9port из любой директории, добавьте каталог bin в переменную окружения PATH. В Bash-подобных оболочках это делается, например, так:
# Откройте файл профиля (пример для bash)
nano /home/$USER/.bash_profile

# Добавьте в конец файла одну из строк (в зависимости от оболочки):
export PATH="$PATH:/home/$USER/plan9port/bin"
# или для zsh
export PATH="$PATH:/home/$USER/plan9port/bin"

После сохранения выйдите из сессии или выполните source /home/$USER/.bash_profile, чтобы обновить PATH в текущей сессии.

Редактирование переменной PATH в текстовом редакторе

Совет: если вы используете system-wide установку или пакетный менеджер (редко встречается для plan9port), проверьте инструкции поставщика пакета. Для локального использования plan9port достаточно добавить bin напрямую в PATH.

Использование и написание простых скриптов rc

Чтобы запустить rc из план9портовского набора утилит, выполните:

9 rc

Команда переключит приглашение оболочки на символ %, что указывает на работу в среде rc. Внутри оболочки доступны и привычные POSIX-утилиты (если они установлены в PATH).

% ls

Пример вывода ls в rc

Ниже раскрыты основные элементы языка rc, которые чаще всего используются при написании скриптов.

Базовые операторы: переменные, файлы, пайпы

rc проектировался для простоты: синтаксис переменных и операций выглядит компактно и последовательно. Основные концепции:

  • Переменные в rc — это просто имена, которым присвоены строки или списки; они не имеют строгих типов.
  • Операции ввода-вывода используют перенаправления и пайпы, похожие на POSIX, но с некоторыми отличиями в выражениях.

Переменные и операции с файлами

Создание и запись значений в переменные простое:

test=hello

Вывод содержимого переменной в файл (append):

echo $test >> world.txt

Чтение из файла как ввод в программу:

cat < world.txt

Обратите внимание на пробелы вокруг операторов и на префикс $ при подстановке переменной.

Переменные и вывод в rc

Важно: в rc меньше специальных правил экранирования по сравнению с bash — строки объявляются одинарными кавычками, и многие управляющие символы внутри них не интерпретируются.

UNIX-пайпы и ветвящиеся пайпы

rc поддерживает традиционные пайпы вида cmd1 | cmd2, но также допускает нетривиальные формы, когда несколько источников направляются в один приёмник. Пример из rc:

cat world.txt | less

Более необычный пример — объединение нескольких потоков как ввода в одну команду с использованием синтаксиса перенаправлений:

cmp <{echo hello} <{echo helloo}

В этом примере обе команды echo создают отдельные подстановки ввода, которые сравниваются cmp. Такой стиль позволяет строить нелинейные конвейеры данных.

Ветвящиеся пайпы и сравнение выводов

Цепочки команд и проверка кодов возврата

В rc можно выполнять несколько команд подряд, разделяя их точкой с запятой:

echo hello-world >> hello.txt; less hello.txt

Для условного выполнения используются операторы && и ||, аналогично POSIX-подходу:

  • cmd1 && cmd2 — выполнить cmd2, если cmd1 завершилась успешно.
  • cmd1 || cmd2 — выполнить cmd2, если cmd1 завершилась с ошибкой.

Пример:

mkdir ./hello && touch ./hello/world

Цепочки и условные операторы в rc

Строки и списки

Основная философия rc — упрощение работы со строками и списками. В отличие от bash, rc использует одинарные кавычки для литералов, что уменьшает путаницу с экранированием.

Пример различия:

# rc
hello='[world]'
# bash
hello='\[world\]'

Списки в rc — это просто группы слов в круглых скобках:

shop=(eggs milk cheese rice beef)

Чтобы вывести элементы списка по индексам (rc использует 1‑начальную нотацию в подстановках), можно применить форму:

echo $shop(123)

Это выведет первые три элемента списка (1,2,3).

Работа со строками и списками в rc

Управление потоком: условия, циклы, функции

rc — полноценный язык для скриптов, который поддерживает условные выражения, циклы и пользовательские функции. Благодаря лаконичному синтаксису многие конструкции записываются компактно и читаются легче, чем их эквиваленты в более громоздких shell-языках.

Пример более сложного кода на rc

Условные операторы

Базовая форма однострочного условного оператора:

if( условие ) действие

Где “условие” — это список команд; любая команда, завершившаяся успешно (код 0), трактуется как “истина”. Например:

if( test -r hello.world ) echo 'there is a hello world!'

Здесь test -r проверяет, доступен ли файл на чтение, и если да — выполняется echo.

Условные операторы в rc

Циклы for

Общий синтаксис однострочного цикла:

for( i in step ) действие

Где step — это либо список элементов, либо результат выполнения программы. Внутри цикла i получает очередное значение.

Пример перебора файлов в каталоге:

for( f in ./hello/* ) if( test -r $f ) echo $f

Циклы for в rc

Функции

Объявление функции в rc простое и компактное:

fn имя {
    набор_команд
}

Пример функции, которая проходит по файлам и сообщает об их наличии:

fn hello {
    for(i in ./hello/*) if(test -r $i) echo 'There is a file here!'
}

Важно: в rc можно писать определения компактно в одну строку или расширенно — выбор зависит от читабельности.

Пример функции в rc

Продвинутые приёмы и обработка ошибок

rc поддерживает гибкие механизм перенаправления файловых дескрипторов. Для разделения диагностического вывода (stderr) и основного (stdout) используется конструкция вида:

./script.rc >[2=1] ./error.log

Это перенаправляет дескриптор 2 (stderr) в файл ./error.log через копирование в дескриптор 1. Такой способ удобен при диагностике и логировании.

Также помните о следующих практиках:

  • Всегда используйте явные проверки существования файла в скриптах, если действия зависят от наличия ресурсов.
  • Для критичных операций делайте резервное копирование или используйте временные файлы перед перезаписью.
  • При переносе скриптов на POSIX-системы учитывайте различия в экранировании и наборе внутренних команд (rc не реализует все bash-расширения).

Сравнение: rc и традиционные оболочки (bash/sh)

Ниже — краткая сравнивающая таблица по ключевым аспектам:

Аспектrcbash / sh
Простота грамматикиОчень лаконична и последовательнаМного исторических исключений и вариантов кавычек
Работа со спискамиВстроенные списки в скобкахМассивы в bash, но синтаксис сложнее
Совместимость с POSIXОграниченная (не POSIX shell)Полная для POSIX-совместных систем
Учебная ценностьВысока — для понимания базовых идей shellВысока — если нужно знать практическую совместимость
Нестандартные возможностиВетки пайпов, простая модель перенаправленийМножество расширений и утилитного кода

Принципиальное правило: выбирайте rc для обучения, экспериментов и там, где важна лаконичность; выбирайте bash/sh для сценариев, которые должны работать на широком наборе серверов и дистрибутивов без дополнительных зависимостей.

Когда rc не подходит

  • Если ваш скрипт должен исполняться в окружениях, где plan9port недоступен или запрещён. Для максимальной переносимости используйте POSIX-совместимые sh-скрипты.
  • Для сложных скриптов со множеством системных проверок лучше использовать bash или язык общего назначения (Python), где есть богатая стандартная библиотека.
  • Если ваша команда уже автоматизирует инфраструктуру с помощью стандартных инструментов CI/CD, добавление нестандартной оболочки усложнит сопровождение.

Практический чеклист: быстрая проверка перед публикацией rc-скрипта

  • [ ] Скрипт запускается в план9port-окружении (проверьте 9 rc).
  • Явно проверены входные файлы и права доступа.
  • Ошибки логируются через перенаправление stderr при необходимости.
  • Нет хардкодированных путей без переменных окружения.
  • В документации указано требование plan9port или инструкция по установке.

Шпаргалка (cheat sheet) — часто используемые шаблоны

# Запуск rc из plan9port
9 rc

# Переменная и вывод
name='Ivan'
echo $name >> out.txt

# Список
shop=(eggs milk cheese)
echo $shop(12)   # вывести первые два элемента

# Цикл
for(i in $shop) echo $i

# Условие
if(test -r file.txt) echo 'file exists'

# Функция
fn greet { echo 'Hello' $1 }

# Перенаправление ошибок
./script >[2=1] error.log

Принятие решений: когда переходить на rc

Mermaid-диаграмма ниже помогает быстро решить, стоит ли пробовать rc в проекте:

flowchart TD
    A[Нужна ли переносимость между серверами?] -->|Да| B[Использовать POSIX / bash]
    A -->|Нет| C[Нужно ли простое и понятное синтаксис?]
    C -->|Да| D[Попробовать rc]
    C -->|Нет| E[Использовать Python или другой язык]
    D --> F{Требуется интеграция с существующими инструментами}
    F -->|Да| B
    F -->|Нет| G[Оставить rc как локальный инструмент]

Ролевые чеклисты

  • Для разработчика:

    • Проверьте окружение plan9port.
    • Напишите тесты для критичных ветвей скрипта.
    • Добавьте краткую документацию для коллег.
  • Для системного администратора:

    • Решите, допустима ли зависимость от plan9port в окружении.
    • Организуйте снапшот или резервную копию перед развёртыванием.
    • Подготовьте fallback-скрипт на POSIX, если требуется.

Частые вопросы

Как узнать количество элементов в списке в rc?

Чтобы получить количество элементов списка, перед именем списка ставят двойную кавычку ". Пример:

echo $"shop

Это выведет число элементов, хранящихся в переменной shop.

Можно ли создать бесконечный цикл в rc?

Да. Для бесконечного цикла в rc можно опустить условие в поле шага, но скобки обязательны. Пример бесконечного вывода:

for(i) echo hello

Этот цикл будет печатать “hello” бесконечно, пока его не прервёт пользователь (Ctrl+C) или внешний сигнал.

Как передавать и логировать ошибки, как >2 в bash?

В rc для управления файловыми дескрипторами используется расширенный синтаксис. Чтобы сохранить ошибки в файл, можно применить:

./script.rc >[2=1] ./error.log

Это направит stderr в файл error.log через копирование дескриптора 2 в дескриптор 1.

Советы по миграции и совместимости

  • Если требуется совместимость с POSIX, оберните критичные участки в POSIX-совместимые скрипты или предоставьте оболочку-адаптер.
  • Для команд, которые используются в скриптах, документируйте поведение и ожидаемые коды возврата.
  • Тщательно тестируйте редиректы и пайпы — поведение может отличаться от bash в пограничных случаях.

Резюме

rc — лаконичная и понятная оболочка, полезная для обучения и локальных автоматизаций. Она доступна в Linux через plan9port и предлагает упрощённую модель работы со строками, списками и потоками ввода-вывода. Для продакшн-скриптов с требованиями переносимости лучше выбирать POSIX-совместимый shell, но для быстрых экспериментов и простых задач rc часто выигрывает за счёт читаемости и прямолинейности.

Важно: перед развёртыванием в командную инфраструктуру оцените совместимость и поддерживаемость plan9port в вашей среде.

Image credits: Unsplash. Все скриншоты: Ramces Red.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько камер в Skype: 3 приложения и советы
Видео

Несколько камер в Skype: 3 приложения и советы

Проверка совместимости ПК с Windows 7
Windows

Проверка совместимости ПК с Windows 7

Starship: быстрый кросс‑оболочный prompt
CLI

Starship: быстрый кросс‑оболочный prompt

Исправление KERNEL_DATA_INPAGE_ERROR — BSoD
Windows

Исправление KERNEL_DATA_INPAGE_ERROR — BSoD

Скачать фото и видео из Facebook
Руководство

Скачать фото и видео из Facebook

Как изменить размер изображения — пошагово
Руководство

Как изменить размер изображения — пошагово