LINUX.ORG.RU

Книга «Командная строка Linux. Полное руководство. 2-е межд. изд.»

 ,

Книга «Командная строка Linux. Полное руководство. 2-е межд. изд.»

6

1

Добрый день! Предлагаю вашему вниманию еще одну книгу — «Командная строка Linux. Полное руководство. 2-е межд. изд.» Ее можно заказать на сайте издательства, и если применить промокод LinuxORG, то получите скидку 30%. Действует на все книги издательства. Также в подарок при покупке бумажной будет ее электронная версия.

Отрывок из книги для ознакомления:

Управление потоком выполнения: циклы while и until

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

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

Циклы

Повседневная жизнь наполнена повторяющимися действиями. Каждодневная поездка на работу, прогулка с собакой и нарезание моркови — все эти действия состоят из повторяющейся последовательности действий. Рассмотрим в качестве примера резку моркови. Этот вид деятельности можно выразить на псевдокоде примерно так:

  1. Взять разделочную доску.
  2. Взять нож.
  3. Положить морковь на доску.
  4. Поднять нож.
  5. Сдвинуть морковь.
  6. Отрезать кусок.
  7. Если вся морковь порезана, завершить операцию, иначе перейти к шагу 4.

Шаги с 4-го по 7-й образуют цикл. Действия внутри цикла повторяются, пока не будет выполнено условие «вся морковь порезана».

while

В bash имеются средства, позволяющие выражать похожие идеи. Представьте, что нам нужно вывести пять чисел по порядку, от 1 до 5. В сценарии на языке bash это можно реализовать, как показано ниже:

#!/bin/bash
# while-count: вывод последовательности чисел
count=1
while [[ $count -le 5 ]]; do
   echo $count
   count=$((count + 1))
done
echo "Finished."

Если запустить этот сценарий, он выведет:

[me@linuxbox ~]$ while-count
1
2
3
4
5
Finished.

Команда while имеет следующий синтаксис:

while команды; do команды; done

Подобно if, команда while проверяет код завершения списка команд. Пока код завершения равен 0, она выполняет команды внутри цикла. В сценарии, приведенном выше, создается переменная count, и ей присваивается начальное значение 1. Команда while проверяет код завершения составной команды [[ ]]. Пока [[ ]] возвращает код 0, команды внутри цикла продолжают выполняться. В конце каждого цикла повторно выполняется команда [[ ]]. После пяти итераций цикла значение переменной count увеличится до 6, команда [[ ]] вернет код завершения,отличный от 0, и цикл завершится, а программа продолжит выполнение с инструкции, следующей непосредственно за циклом.

Цикл while можно использовать для усовершенствования программы read-menu из предыдущей главы:

#!/bin/bash
# while-menu: программа вывода системной информации,
# управляемая с помощью меню
DELAY=3 # Время отображения результатов на экране (в секундах)
while [[ "$REPLY" != 0 ]]; do
   clear
   cat <<- _EOF_
   Please Select:
      1. Display System Information
      2. Display Disk Space
      3. Display Home Space Utilization
      0. Quit
   _EOF_
   read -p "Enter selection [0-3] > "
   if [[ "$REPLY" =~ ^[0-3]$ ]]; then
      if [[ "$REPLY" == 1 ]]; then
         echo "Hostname: $HOSTNAME"
         uptime
         sleep "$DELAY"
      fi
      if [[ "$REPLY" == 2 ]]; then
         df -h
         sleep "$DELAY"
   fi
   if [[ "$REPLY" == 3 ]]; then
      if [[ "$(id -u)" -eq 0 ]]; then
         echo "Home Space Utilization (All Users)"
         du -sh /home/*
      else
         echo "Home Space Utilization ($USER)"
         du -sh "$HOME"
      fi
      sleep "$DELAY"
   fi
else
      echo "Invalid entry."
      sleep "$DELAY"
   fi
done
echo "Program terminated."

Заключив меню в цикл while, мы смогли заставить программу повторять вывод меню после каждой операции выбора. Цикл продолжает выполняться и выводить меню, пока переменная REPLY не получит значение 0, предоставляя пользователю возможность сделать другой выбор. После выполнения выбранной операции выполняется команда sleep, она приостанавливает программу на несколько секунд и дает возможность увидеть результаты до того, как экран будет очищен и на нем вновь появится меню. Когда переменная REPLY получит значение 0, соответствующее варианту «Quit» (выйти), цикл завершится и выполнение продолжится со строки, следующей за done.

Прерывание цикла

В bash имеются две встроенные команды для управления потоком выполнения внутри циклов. Команда break немедленно завершает цикл, после чего выполнение программы продолжается с первой инструкции, следующей за циклом. Команда пропускает оставшуюся часть цикла, и программа переходит к началу следующей итерации цикла. Ниже приводится версия программы while-menu, использующая обе команды — break и continue:

#!/bin/bash
# while-menu2: программа вывода системной информации,
# управляемая с помощью меню
DELAY=3 # Время отображения результатов на экране (в секундах)
while true; do
   clear
   cat <<- _EOF_
      Please Select:
      1. Display System Information
      2. Display Disk Space
      3. Display Home Space Utilization
      0. Quit
   _EOF_
   read -p "Enter selection [0-3] > "
if [[ "$REPLY" =~ ^[0-3]$ ]]; then
   if [[ "$REPLY" == 1 ]]; then
      echo "Hostname: $HOSTNAME"
      uptime
      sleep "$DELAY"
      continue
   fi
   if [[ "$REPLY" == 2 ]]; then
      df -h
      sleep "$DELAY"
      continue
   fi
   if [[ "$REPLY" == 3 ]]; then
      if [[ "$(id -u)" -eq 0 ]]; then
         echo "Home Space Utilization (All Users)"
         du -sh /home/*
      else
         echo "Home Space Utilization ($USER)"
         du -sh "$HOME"
      fi
      sleep "$DELAY"
      continue
   fi
   if [[ "$REPLY" == 0 ]]; then
      break
   fi
  else
     echo "Invalid entry."
     sleep $DELAY
  fi
done
echo "Program terminated."

В этой версии сценария используется бесконечный цикл (цикл, который никогда не завершится сам по себе), в котором команда while проверяет код завершения команды true. Так как true всегда возвращает код 0, цикл никогда не завершится. Этот прием на удивление широко используется в сценариях. Поскольку цикл никогда не завершится сам по себе, программист должен предусмотреть его принудительное прерывание в нужный момент времени. В этом сценарии выход из цикла осуществляется с помощью команды break, когда пользователь выберет пункт 0. В конец других операций добавлена команда continue, чтобы увеличить эффективность работы сценария. Встретив команду continue, сценарий перепрыгнет через остальной код в цикле, который не требуется выполнять для данного выбора. Например, если пользователь выбрал пункт 1, нет никаких причин проверять выбор остальных вариантов.

until

Команда until очень похожа на while, но завершает цикл не когда обнаружит ненулевой код завершения, а наоборот. Цикл until продолжается, пока не получит код завершения 0. В сценарии while-count цикл продолжает выполняться, пока значение переменной count меньше или равно 5. Тот же результат можно получить, переписав сценарий с командой until:

#!/bin/bash
# until-count: вывод последовательности чисел
count=1
until [[ "$count" -gt 5 ]]; do
   echo "$count"
   count=$((count + 1))
done
echo "Finished."

С условным выражением $count -gt 5 команда until завершит цикл в нужный момент времени. Выбор между циклами while и until обычно зависит от того, в каком случае условное выражение будет более читабельным.

Чтение файлов в циклах

Команды while и until могут принимать данные со стандартного ввода. Это дает возможность обрабатывать файлы с их помощью. В следующем примере мы выведем содержимое файла distros.txt, созданного в одной из предыдущих глав:

#!/bin/bash
# while-read: чтение строк из файла
while read distro version release; do
   printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
   "$distro" \
   "$version" \
   "$release"
done < distros.txt

Чтобы перенаправить файл в цикл, мы поместили оператор перенаправления после инструкции done. Цикл будет вводить поля из указанного файла с помощью read. После ввода каждой строки команда read будет завершаться с кодом 0, пока не достигнет конца файла. В этот момент она вернет ненулевой код завершения, и цикл завершится. Цикл можно также использовать в конвейерах:

#!/bin/bash
# while-read2: чтение строк из файла
sort -k 1,1 -k 2n distros.txt | while read distro version release; do
   printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
      "$distro" \
      "$version" \
      "$release"
done

Здесь вывод команды sort передается на стандартный ввод цикла, который выводит поток текста на экран. Но не забывайте, что конвейер выполняет цикл в подоболочке, поэтому после его завершения любые переменные, созданные в цикле, будут потеряны.

Заключение

После знакомства с циклами и ранее представленными командами ветвления, функциями и последовательностями мы получили представление об основных способах управления потоком выполнения в программах. В арсенале bash имеется еще множество хитрых трюков, но все они основаны на этих простых идеях.

Об авторе

Уильям Шоттс (William Shotts) — профессиональный разработчик программного обеспечения с более чем 30-летним стажем, который уже больше 20 лет активно пользуется операционной системой Linux. Имеет богатый опыт разработки программного обеспечения, технической поддержки, контроля качества и написания документации. Также является создателем LinuxCommand.org, образовательного и информационно-просветительского сайта, посвященного Linux, где публикуются новости, обзоры и оказывается поддержка пользующимся командной строкой Linux.

Желаю приятного чтения)

>>> Можно купить на сайте издательства



Проверено: maxcom ()
Последнее исправление: maxcom (всего исправлений: 3)
Ответ на: комментарий от mord0d

Заканчивай переобуваться в прыжке и смешивать два совершенно разных контекста.

Это один и тот же контекст. Попытка слива не засчитана. Старайся ещё.

anonymous
()

Видимо с таким длинным телом топика интерфейс ЛОРа ведёт себя странно. При переходе по ссылке на коммент он дёргается и отлетает выше. А я грешил на Android Chrome.

anonymous
()
Ответ на: комментарий от gremlin_the_red

Обычно не длиннее 5-10, ну и понятно, что скрипт не больше 1 кб. 30 - это край.

crutch_master ★★★★★
()
Ответ на: комментарий от anonymous

Видимо с таким длинным телом топика интерфейс ЛОРа ведёт себя странно. При переходе по ссылке на коммент он дёргается и отлетает выше. А я грешил на Android Chrome.

Оно?

Только у меня наоборот, в Chrome (десктопном) всё нормально, FF глючит.

hobbit ★★★★★
()
Ответ на: комментарий от GP

Очевидно, потому, что ими никто не пользуется ☺

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Psilocybe

Да, там POSIX-совместимый (ну почти) шелл из busybox. Но bash предустановлен, как и в почти любом дистрибутиве Linux.

mord0d ★★★★★
()
Ответ на: комментарий от anonymous

А теперь загляни в рандомный скрипт, в 99.9% случаев ты там увидишь #!/bin/bash (который актуален только в Linux, и то не во всех дистрибутивах), или #!/bin/sh, который рассчитан на то что это будет симлинк на Bash, который в режиме совместимости сожрёт башизмы, но любой другой POSIX-совместимый шелл сфейлится.

mord0d ★★★★★
()
Ответ на: комментарий от hobbit

Оно?

Только у меня наоборот, в Chrome (десктопном) всё нормально, FF глючит.

Да, оно. Chrome на Android (мобильный). А на десктопе FF. Всё верно.

Полагаю, что это как-то связано с близким концом страницы снизу. Например, на этот твой коммент и на выше клик работает нормально. По крайней мере сейчас. А все ниже прыгают.

anonymous
()
Ответ на: комментарий от mord0d

Нет. Или ты притянул за уши Windows в этот контекст не предупредив меня.

Эта попытка тоже ни о чём.

Сначала ты вскукорекивал, что в Windows «ну всё» совместимо. Потом начал вскукорекивать, что в Linux на уровне ядра нет совместимости, потому что дрова пришлось переписывать. Потом я тебе пояснил, что (1) к системным вызовам это никакого отношения не имеет (2) у Windows нужно переписывать драйвера между версиями (вот ведь неожиданность). После чего ты начал нелепо пытаться слиться.

Я твои попытки слиться не засчитываю – старайся ещё.

anonymous
()
Ответ на: комментарий от mord0d

Ты понимаешь, что для обучения неважно какой диалект sh будет использоваться? Освоив один, остальные освоятся в формате чтения справочника.

BceM_IIpuBeT ★★☆☆☆
()

У меня кажись есть она в одном из мягких пакетов, но я на Perl'е все скрипты пишу понятное дело. Вот ещё такая есть. Уже на русском и за ноль долеров можно взять, жадные мои ребятки.

perl5_guy ★★★★★
()
Ответ на: комментарий от mord0d

в 99.9% случаев ты там увидишь #!/bin/bash (который актуален только в Linux

И что с того? Линуксовый шелл как нагибал так и нагибает вендовые нелепости. А то, что разработчик там написал – значит знал что пишет.

или #!/bin/sh, который рассчитан на то что это будет симлинк на Bash

Не. Он рассчитан на то, что там именно sh. Переставай выдумывать. Симлинк на /bin/bash вовсе не означает, что там «башизмы» используются. Если что bash умеет в sh.

но любой другой POSIX-совместимый шелл сфейлится

Скорее нет чем да. Но это не имеет значения.

anonymous
()
Ответ на: комментарий от anonymous

шелл-скрипты, бессистемное сборище исторических костылей и граблей

То ли дело powershell, бессистемное сборище попыток всё переписать с нуля, которое каждые 10 лет депрекейтят :)

olegd ★★★
()
Ответ на: комментарий от BceM_IIpuBeT

Ты цены на востребованые книги смотри, а не на всякий шлак.

Ну пусть «Гарри Поттер 7 книг» - 3800 - это цена в которую заложены и отчисления и хайп.

Всякий шлак - это книги ценой 100-200 руб. Коих можно покупать по несколько книг в месяц для поиска интересных авторов. Но этот шлак вполне себе показывает сколько стоит производство книги.

А цены на IT-книги нынче определяются не отчислениями, не стоимостью производства (чего стоит туалетная бумага «Грокаем алгоритмы»), ни хайпом произведений автора. Их тянут в вверх 100500 курсов программирования за неделю-две. И эфемерные зарплаты программистов.

Почему в конце 90-х – начале 2000-х я мог на стипендию купить себе пару книг, которые сейчас стоят 3000-5000 руб? А когда был в Питере, то пару дней проводил на «Крупе» с большой сумкой для покупок.

Как при таких ценах среднестатистический студент может купить себе эти книги? Только если в его семье доход выше среднего? А если он работает, то эти книги становятся уже не так и нужны.

Так что я вижу причину такой стоимости только в том, что у кого-то в голове: «Смотрите сколько зарабатывают программисты и сколько стоят курсы по программированию. Давайте цену поднимем на ХХХХ руб.»

AlexVR ★★★★★
()
Ответ на: комментарий от anonymous

Про Linux, как и про Windows, я ничего не знаю и знать не хочу, а ты мне пытаешься что-то объяснить, затрачивая на это силы и время. Меня это не беспокоит потому что вы-ход-ной!

mord0d ★★★★★
()
Ответ на: комментарий от BceM_IIpuBeT
  • Однажды приученная обезьянка всегда будет писать #!/bin/bash, потому что в его Ubuntu это работает, а если у вас не работает, то who cares, переходите на Ubuntu;
  • Башизмы делают и без того ленивую обезьянку ещё более ленивой.
mord0d ★★★★★
()
Ответ на: комментарий от anonymous

Линуксовый шелл как нагибал так и нагибает вендовые нелепости.

Да плевать на виндовые cmd.exe и PowerShell. Помимо Linux в UNIX-like мире есть ещё куча всего, и вот там и bash лежит в другом месте (в FreeBSD он лежит в /usr/local/bin/bash, и только после того как будет установлен из пакетов или собран из портов), и /bin/sh от башизмов офигеет и пошлёт обезьянку в пешее эротическое (об этом ниже).

Если что bash умеет в sh.

Но не ругается на башизмы в режиме совместимости с sh.

Скорее нет чем да.

Это лишь предположение, потому что ты ничего кроме Linux не тыкал. Установи FreeBSD и удивись.

Но это не имеет значения.

Ну-ну. ☺

mord0d ★★★★★
()
Ответ на: комментарий от BceM_IIpuBeT

Чойта?! Когда-то Linux.Org.Ru крутился на кошерной FreeBSD (потому что Linux нишмок!), так что я имею полное право. :3

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Проблемы пермиссивщиков никого не волнуют. Только они по религиозным причинам выпиливают GPL софт из базы. ССЗБ.

BceM_IIpuBeT ★★☆☆☆
()
Ответ на: комментарий от BceM_IIpuBeT

Только они по религиозным причинам выпиливают GPL софт из базы.

Да что ты говоришь! xD

А в ядре Linux, значит, не ставят палки в колёса non-GPL коду? xD

Напомнить как регулярно ломают nvidia, ZFS, иногда ломают vmware?

Пермиссивщики защищаются от вирусности GPL, чтобы они не отжали свободный пермиссивный код!

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Это лишь предположение, потому что ты ничего кроме Linux не тыкал. Установи FreeBSD и удивись.

Если что в Убунту стоит dash. И он прекрасно работает. И прочее и прочее. Кстати, ты прыгая с темы почему-то шелл со файликами скриптов начал путать. Всё что нужно от шелла – иметь в себе sh. Всё. Остальное на усмотрение пользователя и в его компетенции. Давай установи FreeBSD и удивись.

anonymous
()
Ответ на: комментарий от mord0d

Про Linux, как и про Windows, я ничего не знаю и знать не хочу, а ты мне пытаешься что-то объяснить, затрачивая на это силы и время. Меня это не беспокоит потому что вы-ход-ной!

То что ты ничего не знаешь и так понятно. Мог бы не пояснять.

anonymous
()
Ответ на: комментарий от mord0d

А в ядре Linux, значит, не ставят палки в колёса non-GPL коду

Пермиссивщики защищаются от вирусности GPL

Это уже ШУЕ какое-то.

BceM_IIpuBeT ★★☆☆☆
()
Ответ на: комментарий от GP

Интересно, почему не выпускают книги по командной строке DOS и Windows?

Выпускают:

  1. Уильям Р. Станек. Командная строка Microsoft Windows. Справочник администратора
  2. Попов А. Командная строка и сценарии Windows
  3. Клименко Р.А. Недокументированные и малоизвестные возможности Windows XP

Украдено с киберфорума

Из более современного — «Введение в Windows PowerShell» того же (видимо) А.Попова.

Из более древнего, т.е. по собственно DOS, так вообще много, в т.ч. от отечественных авторов: Брябрин, Фроловы и др.

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 3)
Ответ на: комментарий от anonymous

Давай установи FreeBSD и удивись.

 % uname -srm
FreeBSD 13.0-RELEASE amd64
 % freebsd-version -r
13.0-RELEASE
 % sysctl kern.ostype
kern.ostype: FreeBSD
 % sysctl kern.osrelease
kern.osrelease: 13.0-RELEASE

Дальше что? Назвать скрипты, в которых #!/bin/sh, но они не работают? Обойдёшься.

mord0d ★★★★★
()
Ответ на: комментарий от BceM_IIpuBeT

Прежде чем упрекать чужой цирк, со своим разберись. =P

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Дальше что? Назвать скрипты, в которых #!/bin/sh, но они не работают?

Причём тут какие-то скрипты. Ставь чрез wine рядом cmd.exe и работай в ней. Потом подойдёшь.

anonymous
()
Ответ на: комментарий от Odalist

А можно бесплатно скачать электронную версию книги, или зажали?

А ты напиши книгу сам, потрать на неё своё время, а потом отдавай бесплатно, или зажмёшь?

Alve ★★★★★
()
Ответ на: комментарий от anonymous

Причём тут какие-то скрипты.

А книга про что? В интерактиве лупы нужны раз в тыщу лет.

mord0d ★★★★★
()
Ответ на: комментарий от Alve

А ты напиши книгу сам, потрать на неё своё время, а потом отдавай бесплатно

Так автор сабжевой книги так и поступил. ☺

gremlin_the_red ★★★★★
()

все кому это нужно уже скачали на рутрекере!:-)

jester-666
()
Ответ на: комментарий от BceM_IIpuBeT

У вас логика отклеилась. Людьми не будет использовано меньше пластика если больше книг будут бумажными. Производство гаджетов от этого не уменьшится. А вот вырубку лесов, если бумажные книги станут не нужны, возможно уменьшить.

Jax_iv
()
Ответ на: комментарий от mord0d

А теперь загляни в рандомный скрипт, в 99.9% случаев ты там увидишь #!/bin/bash (который актуален только в Linux, и то не во всех дистрибутивах), или #!/bin/sh, который рассчитан на то что это будет симлинк на Bash, который в режиме совместимости сожрёт башизмы, но любой другой POSIX-совместимый шелл сфейлится.

В Debian #!/bin/sh указывает на /bin/dash. И это, соответственно, наверное, во всех производных, включая Ubuntu.

Zubok ★★★★★
()
Ответ на: комментарий от BceM_IIpuBeT

я недавно по работе был привлечён, фришка, bash отсутствует как класс, ставить допы не одобряется. мучился с «немецким» шелом :)

mumpster ★★★★★
()
Ответ на: комментарий от Jax_iv

Людьми не будет использовано меньше пластика если больше книг будут бумажными. Производство гаджетов от этого не уменьшится. А вот вырубку лесов, если бумажные книги станут не нужны, возможно уменьшить.

Если следовать всем прихотям экофанатиков, то нам вообще надо прекратить любое производство, отменить цивилизацию, перейти к примитивному собирательству, а ещё лучше - просто выпилиться, чтобы не мешать «Матери Земле».

IRASoldier ★★
()
Ответ на: комментарий от Zubok

И это, соответственно, наверное, во всех производных

Совершенно не обязательно.

mord0d ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.