По вопросам о скриптах, написанных для командной оболочки Bash. Для сценариев оболочки с ошибками / синтаксическими ошибками, пожалуйста, проверьте их с помощью программы shellcheck (или на веб-сервере shellcheck по адресу https://shellcheck.net), прежде чем размещать здесь. Вопросы об интерактивном использовании Bash, скорее всего, будут касаться темы суперпользователя, чем stackru.

О Баше

Существует множество интерпретаторов, которые принимают команды в интерактивном режиме или в виде последовательности команд из файла. Борна-снова оболочки (Bash) являются одним из таких интерпретатор. Bash реализует стандартную оболочку Bourne Shell (sh) и предлагает множество дополнений.

Со страницы Bash Фонда свободного программного обеспечения:

Баш - это sh-совместимая оболочка, которая включает полезные функции из KornShell (ksh) и оболочки C (csh). Он предназначен для соответствия стандарту оболочки и инструментов IEEE POSIX P1003.2/ISO 9945.2. Он предлагает функциональные улучшения по сравнению с sh как для программирования, так и для интерактивного использования. Кроме того, большинство сценариев sh можно запускать с помощью Bash без изменений.

Прочтите руководство Bash для получения технических подробностей.

Bash был написан Брайаном Фоксом и впервые выпущен в 1989 году. Это оболочка по умолчанию во многих дистрибутивах Linux и в MacOS; он доступен в большинстве современных операционных систем и перенесен на Windows 10.

Примечание относительно версий

По состоянию на январь 2019 года самая последняя версия bash 5.0, хотя вы можете использовать старую версию в зависимости от вашей операционной системы и обновлений для bashбыли установлены. В большинстве установок Linux должно использоваться что-то из семейства 4.x. macOS (ранее Mac OS X) по умолчанию использует версию 3.2 из-за проблем с лицензированием.

Обязательно укажите в своем вопросе, какая версия bashты используешь. Это предупредит потенциальных респондентов о том, какие функции вам доступны, а также о том, какие ошибки, возможно, необходимо исправить.

Вы можете определить, какая версия bash вы используете, запустив bash --version или проверяя значение BASH_VERSION переменная оболочки.

Без явной версии ответчик может предположить, что вы используете версию не ниже 4.2. Вопросы с тегамиosx подразумевается версия 3.2, если не указано иное.

Краткая история выпуска

На основе загрузок с http://ftp.gnu.org/gnu/bash/

Version    Release date
=======================
3.2        2006-10-11
4.0        2009-02-20
4.1        2009-12-31
4.2        2011-02-13
4.3        2014-02-26
4.4        2016-09-15
5.0        2019-01-07

Дополнительно все версии для bash от 2.0 и более поздних версий в сентябре 2014 года был выпущен важный выпуск на уровне исправлений для устранения уязвимости Shellshock.

Прежде чем спрашивать о проблемном коде

Чтобы помочь добрым людям, которые помогают вам, чтобы будущие читатели могли извлечь пользу из вашего вопроса, и чтобы ваш вопрос был признан полезным для этой прекрасной кармы, пожалуйста, сделайте свой вопрос как можно более простым и универсальным:

  1. Проверьте, есть ли в вашем скрипте или данных символы конца строки в стиле DOS
  • Использовать cat -v yourfile или echo "$yourvariable" | cat -v.

    Возврат каретки DOS будет отображаться как ^M после каждой строчки.

    Если вы их найдете, удалите их с помощью dos2unix (он же fromdos) или tr -d '\r'

  1. Убедитесь, что вы запускаете скрипт с bashне sh
  • Первая строка в скрипте должна быть #!/bin/bash или #!/usr/bin/env bash.

    Не должно быть#!/bin/sh

  • Запустите сценарий с ./yourscript или bash yourscript.

    Не запускайте его сsh yourscript.

Это применимо даже тогда, когда sh символическая ссылка на bash.

  1. Найдите небольшой самодостаточный пример.
  • Не включайте разделы и команды, не связанные с вашей проблемой.
  • Избегайте сложных команд, которые служат только для получения значения (включая значение напрямую).
  • Не полагайтесь на внешние файлы. Создавайте файлы на лету, включайте данные напрямую или опубликуйте небольшой пример файла в своем вопросе.
  1. Проверьте свой пример. Убедитесь, что он работает и по-прежнему показывает проблему. Не отмахивайтесь от этого.
  • Переформатирование для наглядности часто позволяет избежать ошибок, связанных с интервалом и именованием.
  • Рефакторинг для простоты часто позволяет избежать ошибок, связанных с подоболочками.
  • Имитация файлов и данных часто позволяет обойти проблемы, связанные со специальными символами.
  • Часы, потраченные на попытки нескольких вещей, часто приводят к публикации кода из одной версии и ошибок из другой.
  1. Проверьте пример на общие проблемы
  • Протестируйте свой пример shellcheckили онлайн-сервис shellcheck для автоматической проверки типичных ошибок.
  • Обзор Bash подводные камни и ошибки новичка в Bash, а также вопросы Популярные ниже раздел перечней общих вопросов.
  • Проверьте свои данные на наличие специальных символов, используя cat -v yourfile или cat -v <<< "$yourvar". Будьте особенно осторожны с возвратом каретки (показано как^M).
  1. Пожалуйста, не помечайте вопросы, касающиеся исключительно внешних команд. Вbash Тег должен быть зарезервирован для проблем, связанных с Bash, а не для любых проблем с интерфейсом командной строки, которые могут у вас возникнуть.

Как превратить плохой сценарий в хороший вопрос

Например, предположим, что у вас есть сценарий для предупреждения вас, когда сервер простаивает, но он продолжает предупреждать, даже когда машина не простаивает:

# Avoid code like this when asking about a problem
# It has irrelevant code and external dependencies, and is hard to read and run

while true
do
  load=$(wget -O - "http://$1/load.php" | grep "^load:" | cut -d: -f 2)
  if [[ $load=="0" ]]
  then 
    mailx -s "System is idle" user@example.com <<< "The server is idle"
    break
  else
    echo "Waiting..."
    sleep 60
  fi
done
  1. Проблема по-прежнему возникает без цикла: удалите цикл из вашего вопроса.
  2. Проблема все еще возникает, если вы пропустите запрос сервера: жестко закодируйте ответ (например, load=42)
  3. Проблема по-прежнему возникает без отправки по электронной почте: используйте echo "Why does this run?"
  4. Проблема все еще возникает при удалении ветки else. Сократите это

Теперь у нас остался этот небольшой самодостаточный пример:

# Prefer code like this when asking about a problem
# It's small, simple and self contained, making it easy to read and run.

load=42
if [[ $load=="0" ]]
then
  echo "Why does this run?"
fi

Спасибо за простой и полезный вопрос! Наслаждайтесь своими голосами!

(Однако обратите внимание, что этот пример легко сравнить с соответствующей записью в ловушках Bash, и ошибка автоматически обнаруживаетсяshellcheck, так что теперь вам не нужно спрашивать!)

Популярные вопросы

Некоторые часто задаваемые вопросы о Bash включают следующее.

Базовый синтаксис и общие проблемы новичков

Некоторые основы Bash удивляют даже ветеранов других языков программирования.

Как мне...?

Почему...?

Общие задачи

Эти вопросы на самом деле не относятся к Bash, но достаточно часто встречаются в этом теге, поэтому их стоит включить здесь.

Мета

Книги и ресурсы

Дополнительные материалы для чтения включают:

инструменты

  • shellcheck - инструмент статического анализа, выявляющий типичные ошибки
  • он-лайн ShellCheck, веб-сервер, обеспечивающий проверку оболочки (полезно, если вы еще не установили программу)

Чат

stackrubashчат полезен для координации работы в рамках этого тега и, возможно, иногда для получения быстрой помощи (хотя никаких гарантий быть не может; посещаемость невысока).