You are on page 1of 133

Machine Translated by Google

Machine Translated by Google


Machine Translated by Google

LINUX SHELL
ПРОГРАМИРАНЕ
Джобен буквар
Machine Translated by Google

ЛИЦЕНЗ, ОТКАЗ ОТ ОТГОВОРНОСТ И LIMITED


ГАРАНЦИЯ

Със закупуването или използването на тази книга и придружаващите я файлове


(„Произведението“), вие се съгласявате, че този лиценз дава разрешение за използване
на съдържащото се тук съдържание, включително диска, но не ви дава правото на
собственост върху каквото и да е текстово съдържание в книгата/диска или собственост
върху която и да е информация или продукти, съдържащи се в него. Този лиценз не
позволява качване на Произведението в Интернет или в мрежа (от всякакъв вид) без
писменото съгласие на Издателя. Дублирането или разпространението на какъвто и да е
текст, код, симулации, изображения и т.н., съдържащи се тук, е ограничено до и подлежи
на лицензионни условия за съответните продукти и трябва да се получи разрешение от
Издателя или собственика на съдържанието и т.н., за да за възпроизвеждане или
свързване в мрежа на която и да е част от текстовия материал (във всякакви медии), който се съдържа в

MERCURY LEARNING AND INFORMATION („MLI“ или „Издателят“) и всеки, участващ в


създаването, писането или производството на придружаващия диск, придружаващите
алгоритми, код или компютърни програми („софтуерът“) и всеки придружаващ уеб
сайт или софтуер на Произведението, не може и не гарантира изпълнението или
резултатите, които могат да бъдат получени чрез използване на съдържанието на
Произведението. Авторът, разработчиците и издателят са положили всички усилия,
за да гарантират точността и функционалността на текстовия материал и/или
програмите, съдържащи се в този пакет; ние обаче не даваме никаква гаранция от
какъвто и да било вид, изрична или подразбираща се, по отношение на работата на
това съдържание или програми. Произведението се продава „както е“ без гаранция
(с изключение на дефектни материали, използвани при производството на книгата,
или поради дефектна изработка).

Авторът, разработчиците и издателят на всяко придружаващо съдържание, както и всеки,


участващ в композирането, производството и производството на това произведение,
няма да носи отговорност за щети от какъвто и да е вид, произтичащи от използването на
(или невъзможността да се използва) алгоритми, изходен код, компютърни програми или
текстови материали, съдържащи се в тази публикация. Това включва, но не се ограничава
до загуба на приходи или печалба, или други случайни, физически или последващи щети,
произтичащи от използването на това произведение.
Machine Translated by Google

Единственото обезщетение в случай на иск от какъвто и да е вид е изрично


ограничено до замяна на книгата и/или диска и само по преценка на Издателя.
Използването на „подразбираща се гаранция“ и определени „изключения“ варира
в зависимост от държавата и може да не се отнася за купувача на този продукт.

Придружаващите файлове за това заглавие са достъпни, като пишете на издателя


на info@merclearning.com.
Machine Translated by Google

ПРОГРАМИРАНЕ НА LINUX SHELL


Джобен буквар

Освалд Кампесато

УЧЕНЕ И ИНФОРМАЦИЯ ЗА МЕРКУРИЙ

Дълес, Вирджиния
Бостън, Масачузетс
Ню Делхи
Machine Translated by Google

Авторско право ©2023 от MERCURY LEARNING AND INFORMATION LLC. Всички права запазени.

Тази публикация, части от нея или който и да е придружаващ софтуер не могат да бъдат възпроизвеждани по никакъв
начин, съхранявани в система за извличане от какъвто и да е тип или предавани по какъвто и да е начин, носител,
електронен дисплей или механичен дисплей, включително, но не само, фотокопие , записване, публикации в
Интернет или сканиране без предварително писмено разрешение от издателя.

Издател: Дейвид Палай

MERCURY ОБУЧЕНИЕ И ИНФОРМАЦИЯ 22841 Quicksilver

Drive Dulles, VA 20166


info@merclearning.com
www.merclearning.com
800-232-0223

О. Кампесато. Джобен пример за програмиране на Linux Shell.


ISBN: 978-1-68392-621-4

Издателят признава и уважава всички марки, използвани от компании, производители и разработчици като средство за
разграничаване на техните продукти. Всички имена на марки и продукти, споменати в тази книга, са търговски марки
или марки за услуги на съответните компании. Всяко пропускане или злоупотреба (от всякакъв вид) на марки за услуги
или търговски марки и т.н. не е опит за нарушаване на чужда собственост.

Контролен номер на Библиотеката на Конгреса: 2023937874


232425321 Тази книга е отпечатана на несъдържаща киселина хартия в Съединените американски щати.

Нашите заглавия са достъпни за осиновяване, лицензиране или закупуване на едро от институции, корпорации и др.
За допълнителна информация, моля, свържете се с отдела за обслужване на клиенти на 800-232-0223 (безплатен).

Всички наши заглавия са достъпни в цифров формат на academicourseware.com и други дигитални доставчици.
Придружаващите файлове (фигури и списъци с кодове) за това заглавие са достъпни, като се
свържете с info@merclearning.com. Единственото задължение на MERCURY LEARNING AND INFORMATION към купувача е да
замени диска въз основа на дефектни материали или дефектна изработка, но не и въз основа на работата или
функционалността на продукта.
Machine Translated by Google

Бих искал да посветя тази книга на моите


родители – нека това донесе радост и щастие в живота им.
Machine Translated by Google

СЪДЪРЖАНИЕ

Предговор

Глава 1: Въведение Unix срещу


Linux Налични типове

обвивки Какво е bash?

Получаване на помощ за команди bash


Навигиране из директории Командата
history Изброяване на
имената на файлове с командата ls Показване на
съдържанието на файловете Командата
cat Командите head и
tail Символът Pipe Командата fold

Собственост на файла: собственик, група и свят


Скрити файлове

Обработка на проблемни имена на файлове


Работа с променливи на средата
Командата env
Полезни променливи на средата

Задаване на променливата на средата PATH


Указване на псевдоними и променливи на средата
Намиране на изпълними файлове
Командата printf и командата echo
Командата за изрязване
Machine Translated by Google

Командата echo и интервали


Замяна на команда (обратна маркировка)
Символът за тръба и множество команди
Използване на точка и запетая за разделяне на команди
Командата за поставяне
Вмъкване на празни редове с командата paste
Лесен случай на използване с командата paste
Лесен случай на използване с команди за изрязване и поставяне
Работа с метазнаци
Работа с символни класове
Работа с “^” и “\” и “!”
Какво ще кажете за zsh?

Превключване между bash и zsh


Конфигуриране на
zsh Резюме

Глава 2: Файлове и директории

Създавайте, копирайте, премахвайте и премествайте файлове

Създаване на текстови файлове

Копиране на файлове

Копиране на файлове със заместване на команди


Изтриване на файлове

Преместване на файлове

Командването

Командите за основно име, име на директория и файл


Командата wc
Командата на котката
Колкото повече командване и толкова по-малко командване

Главното командване
Команда за опашката

Сравняване на съдържанието на файла


Частите на името на файла
Работа с разрешения за файлове
Командата chmod

Промяна на собственика, разрешенията и групите


Командите umask и ulimit

Работа с указатели
Machine Translated by Google

Абсолютни и относителни директории


Абсолютни/относителни имена на пътища

Създаване на директории
Премахване на директории
Навигиране до директории
Преместване на директории

Използване на кавички
Потоци и команди за пренасочване
Метазнаци и класове знаци

Цифри и знаци
Имена на файлове и метасимволи
Резюме

Глава 3: Полезни команди

Командата за присъединяване
Командата за сгъване

Командата за разделяне
Командата за сортиране

Уникалната команда
Как да сравняваме файлове
Командата od
Командата tr

Лесен случай на употреба


Командата намиране
Командата за чай

Команди за компресиране на файлове


Командата tar

Командата cpio
Командите gzip и gunzip
Командата bunzip2
Командата zip
Команди за zip файлове и bz файлове
Вътрешен разделител на полето (IFS)
Данни от диапазон от колони в набор от данни
Работа с неравномерни редове в набори от данни
Резюме
Machine Translated by Google

Глава 4: Условна логика и цикли

Бърз преглед на операторите в bash


Аритметични операции и оператори
Командата expr
Аритметични оператори
Булеви и числови оператори
Съставни оператори и числови оператори
Работа с променливи
Присвояване на стойности на променливи

Командата за четене за потребителско въвеждане

Булеви оператори и низови оператори


Съставни оператори и низови оператори
Оператори за тестване на файлове

Сложни оператори и файлови оператори


Условна логика с оператори if/else/fi
Декларацията за случая/esac

Работа с низове в скриптове на Shell


Работа с Loops
Използване на for Loop
Проверка на файлове в директория
Работа с вложени цикли
Използване на цикъла while
Операциите while, case и if/elif/else/fi
Използване на цикъл до
Дефинирани от потребителя функции

Създаване на просто меню от команди на Shell


Масиви в bash
Работа с масиви
Резюме

Глава 5: Филтриране на данни с grep Какво

представлява командата grep?


Метасимволи и командата grep Ескейпиране
на метасимволи с командата grep Полезни опции за
командата grep
Класове символи и командата grep
Работа с опцията -c в grep
Machine Translated by Google

Съпоставяне на диапазон от линии


Използване на обратни препратки в командата grep
Намиране на празни редове в набори от данни

Използване на ключове за търсене на набори от данни

Символът обратна наклонена черта и командата grep


Множество съвпадения в командата grep
Командата grep и командата xargs
Търсене на низ в zip файлове
Проверка за уникална стойност на ключ
Пренасочване на съобщения за грешка

Командата egrep и командата fgrep


Показване на „чисти“ думи в набор от данни с egrep
Командата fgrep
Лесен случай на употреба
Резюме

Глава 6: Трансформиране на данни с sed Какво


представлява командата sed?
Цикълът на изпълнение на sed
Съпоставяне на низови модели Използване на sed

Заместване на низови модели с помощта на sed


Замяна на гласни от низ или файл
Изтриване на множество цифри и букви от низ
Търсене и замяна със sed
Набори от данни с множество разделители
Полезни превключватели в sed

Работа с набори от данни


Печат на линии
Класове на знаци и sed

Премахване на контролни знаци


Преброяване на думи в набор от данни
Обратно Препратки в sed
Показване само на „чисти“ думи в набор от данни
Едноредови sed команди
Резюме

Глава 7: Правене на всичко останало с awk


Machine Translated by Google

Командата awk
Вградени променливи, които
контролират awk Как работи командата awk?
Подравняване на текст с командата printf() Условна логика
и оператори за управление
Изявлението while

Цикъл for в awk


Цикъл for с команда за прекъсване
Следващият и продължете изявления

Изтриване на алтернативни редове в набори от данни

Обединяване на линии в набори от данни

Отпечатване на съдържанието на файла като един ред

Обединяване на групи от редове в текстов файл


Съединяване на алтернативни редове в текстов файл

Съпоставяне с метасимволи и набори от знаци


Отпечатване на редове с помощта на условна логика
Разделяне на имена на файлове с awk
Работа с аритметични оператори Postfix
Числени функции в awk
Едноредови awk команди

Полезни кратки awk скриптове


Отпечатване на думите в текстов низ в awk
Преброяване на срещанията на низ в определени редове
Отпечатване на низ във фиксиран брой колони
Отпечатване на набор от данни във фиксиран брой колони
Подравняване на колони в набори от данни

Подравняване на колони и множество редове в набори от данни


Премахване на колона от текстов файл
Подмножества от подравнени по колони редове в набори от данни

Преброяване на честотата на думите в наборите от данни

Показване само на „чисти“ думи в набор от данни


Работа с многоредови записи в awk
Лесен случай на употреба
Друг случай на употреба

Резюме

Глава 8: Въведение в скриптовете и функциите на Shell


Machine Translated by Google

Какво представляват скриптовете на Shell?

Прост скрипт на Shell


Задаване на променливи на средата чрез скриптове на Shell
Снабдяване или „начертаване“ на Shell Script
Работа с функции в скриптове на Shell
Предаване на стойности към функции в Shell скрипт (1)
Предаване на стойности към функции в Shell скрипт (2)
Итериране на стойности, предадени на функция
Позиционни параметри в дефинирани от потребителя функции

Shell скриптове, функции и въвеждане от потребителя


Рекурсия и Shell скриптове
Итеративни решения за факторни стойности
Изчисляване на числата на Фибоначи
Изчисляване на НОД на две положителни цели числа
Изчисляване на LCM на две положителни цели числа
Изчисляване на първични делители
Резюме

Глава 9: Shell скриптове с командите grep и awk

Командата grep
Симулиране на релационни данни с командата grep
Проверка на актуализациите в регистрационен файл

Обработка на многоредови записи


Добавяне на съдържанието на записите
Използване на функцията split в awk
Сканиране на диагонални елементи в набори от данни
Добавяне на стойности от множество набори от данни (1)
Добавяне на стойности от множество набори от данни (2)
Добавяне на стойности от множество набори от данни (3)
Изчисляване на комбинации от стойности на полета
Резюме

Глава 10: Разни скриптове на Shell

Използване на rm и mv с директории
Използване на командата find с директории
Създаване на указател на указатели
Клониране на набор от поддиректории
Machine Translated by Google

Изпълнение на файлове в множество директории


Командата case/esac

Компресиране и декомпресиране на файлове


Командата dd
Командата crontab

Декомпресиране на файлове като работа на cron

Планирани команди и фонови процеси


Как да планирате задачи

Командата nohup
Изпълнение на команди от разстояние
Как да планирате задачи във фонов режим
Как да прекратим процесите

Прекратяване на множество процеси


Свързани с процеса команди
Как да наблюдаваме процесите

Проверка на резултатите от изпълнението

Системни съобщения и регистрационни файлове

Команди за използване на диска

Прихващане и игнориране на сигнали


Аритметика с командите bc и dc

Работа с командата за дата


Команди, свързани с печата

Създаване на отчет с командата printf().


Проверка на актуализациите в регистрационен файл

Изброяване на активни потребители на машина


Разни команди

Резюме

Индекс
Machine Translated by Google

ПРЕДГОВОР

КАКВА Е ЦЕЛТА?

Целта на тази книга е да запознае читателите с набор от мощни помощни програми


за команден ред, които могат да се комбинират за създаване на прости, но мощни
скриптове на обвивката. Въпреки че всички примери и скриптове използват набора от
команди „bash“, много от концепциите се превеждат в други форми на скриптове на
обвивката (ksh, sh, csh), включително концепцията за прехвърляне на данни между
командите, заместване на регулярен израз и командите sed и awk . Насочена към читател,
който е сравнително нов в работата в bash среда, книгата е достатъчно изчерпателна, за
да бъде добра справка и да научи на няколко нови трика тези, които вече имат известен
опит със създаването на скриптове на shell.
Тази кратка книга съдържа разнообразни фрагменти от код и скриптове за обвивка
за учени по данни, анализатори на данни и други хора, които искат базирани на обвивка
решения за „почистване“ на различни типове набори от данни. Освен това концепциите
и примерните кодове в тази книга са полезни за хора, които искат да опростят рутинни
задачи.
Книгата съдържа уводни концепции и команди в bash и след това демонстрира
използването им в мощни шел скриптове. Той не обхваща „чистата“ функционалност за
системно администриране за Linux.

ТАЗИ КНИГА ЛИ Е ЗА МЕН И КАКВО ЩЕ НАУЧА?

Тази книга е предназначена за обикновени потребители, специалисти по данни,


анализатори на данни и други хора, които изпълняват различни задачи от командния
ред и които също имат скромни познания по програмиране на shell. Съдържанието ще се запази
Machine Translated by Google

време, необходимо за търсене на подходящи примерни кодове и адаптирането им


към вашите специфични нужди, което е потенциално отнемащ време процес.
Ще придобиете разбиране как да използвате различни bash команди, често като
част от кратки скриптове на обвивката. Главите също съдържат прости случаи на
употреба, които илюстрират как да изпълнявате различни задачи, включващи набори
от данни, като например смяна на реда на набор от данни с две колони (Глава 1),
премахване на контролни знаци в текстов файл (Глава 2), намиране на конкретни
редове и сливане тях (Глава 3) и използване на условна логика в shell скрипт (Глава 4).
Глави 5, 6 и 7 се фокусират съответно върху bash командите grep, sed и awk. След
това Глава 8 съдържа подробности относно shell скриптовете, последвана от Глава 9 ,
която съдържа shell скриптове, включващи командите и awk . И накрая, grep
Глава 10
включва различни примери за shell скриптове, като работа с zip файлове, планиране
на shell скриптове с помощта на crontab и как да генерирате прости отчети.

КАК СА СЪЗДАДЕНИ ПРИМЕРИТЕ НА КОД?

Примерите за код в тази книга са създадени и тествани с помощта на bash на


MacBook Pro с OS X 10.12.6 (macOS Sierra). По отношение на тяхното съдържание:
примерните кодове са извлечени основно от скриптове, изготвени от автора, а в
някои случаи има примерни кодове, които включват кратки части от код от дискусии в
онлайн форуми. Ключовият момент, който трябва да запомните, е, че примерните
кодове следват „Четирите C“: те трябва да бъдат ясни, кратки, пълни и правилни до
степента, до която е възможно да се направи това, като се има предвид покритието на
тази книга.

КАКВО ТРЯБВА ДА ЗНАЕТЕ ЗА ТАЗИ КНИГА

Имате нужда от известни познания за работа от командния ред в Unix-подобна


среда. Съществуват обаче субективни предпоставки, като например желание да
научите програмиране в shell, заедно с мотивация и дисциплина за четене и разбиране
на примерните кодове. Във всеки случай, ако не сте сигурни дали можете или не
можете да усвоите материала в тази книга, прегледайте примерните кодове, за да
усетите нивото на сложност.

КОИ BASH КОМАНДИ СА ИЗКЛЮЧЕНИ?


Machine Translated by Google

Командите, които не отговарят на нито един от критериите, изброени в предишния


раздел, не са включени в тази книга. Следователно няма покритие на команди за системно
администриране (напр. изключване на машина, планиране на архивиране и т.н.). Целта
на материала в главите е да илюстрира как да използвате bash команди за обработка на
общи задачи за почистване на данни с набори от данни, след което можете да прочетете
допълнително, за да задълбочите знанията си.

КАК ДА НАСТРОЙЯ КОМАНДНА ОБВИВКА?

Ако сте потребител на Mac, има три начина да го направите. Първият метод е да
използвате Finder , за да отидете до Приложения > Помощни програми и след това
щракнете два пъти върху приложението Помощни програми . След това, ако вече имате
налична командна обвивка, можете да стартирате нова командна обвивка, като напишете
следната команда:

отворете /Applications/Utilities/Terminal.app

Втори метод за потребителите на Mac е да отворят нова командна обвивка на


MacBook от командна обвивка, която вече е видима, просто като щракнете върху
command+n в тази командна обвивка и вашият Mac ще стартира друга командна обвивка.

Ако сте потребител на компютър, можете да инсталирате Cygwin (с отворен код


https://cygwin.com/) който симулира bash команди или използвайте друг инструментариум
като MKS (комерсиален продукт). Моля, прочетете онлайн документацията, която описва
процеса на изтегляне и инсталиране.
Ако използвате RStudio, ще стартирате командна обвивка вътре в RStudio, като
отидете на Инструменти > Команден ред и след това можете да стартирате bash команди.
Обърнете внимание, че персонализираните псевдоними не се задават автоматично, ако
са дефинирани във файл, различен от основния файл за стартиране (като .bash_login).

КАКВИ СА „СЛЕДВАЩИТЕ СТЪПКИ“ СЛЕД ЗАВЪРШВАНЕТО НА КНИГАТА?

Отговорът на този въпрос варира значително, главно защото зависи до голяма


степен от вашите цели. Едно практическо предложение е да опитате нов инструмент или
техника от книгата за проблем или задача, която ви интересува, професионално или
лично. Какво точно може да бъде това зависи от това кой сте, като
Machine Translated by Google

нуждите на учените по данни, мениджърите, студентите или разработчиците са различни.


Освен това имайте предвид наученото, докато се справяте с нови задачи или
предизвикателства. Понякога осъзнаването, че дадена техника е възможна, прави
намирането на решение по-лесно, дори ако трябва да прочетете отново раздела, за да
запомните как точно работи синтаксисът.
Ако сте достигнали границите на това, което сте научили тук и искате да получите
допълнителна техническа дълбочина на тези команди, има голямо разнообразие от
налична литература, както и онлайн ресурси, описващи bash shell и командите grep, sed и
awk .
Machine Translated by Google

ГЛАВА 1

ВЪВЕДЕНИЕ

T
неговата глава ви запознава с основните команди в bash shell, като напр
навигиране из файловата система, изброяване на файлове и показване на
съдържанието на файловете. Тази глава е плътна и съдържа еклектична
комбинация от теми, за да ви подготви бързо за следващите глави. Ако вече имате
известни познания по програмиране на shell, вероятно можете бързо да прегледате
тази уводна глава и да продължите към Глава 2.
Първата част на тази глава започва с кратко въведение в някои обвивки на Unix и
след това обсъжда файлове, разрешения за файлове и директории. Ще научите също
как да създавате файлове и директории и как да променяте разрешенията за достъп
до тях.
Втората част на тази глава представя прости скриптове на обвивката, заедно с
инструкции как да ги направите изпълними. Shell скриптовете съдържат bash команди
(и по избор могат да съдържат дефинирани от потребителя функции), така че е добра
идея да научите за bash командите, преди да можете да създавате shell скриптове
(което включва bash скриптове).
Третата част от тази глава обсъжда две полезни bash команди: командата cut (за
изрязване или извличане на колони и/или полета от набор от данни) и командата
paste (за „поставяне“ на текст или набори от данни заедно вертикално).

В допълнение, последната част на тази глава съдържа случай на използване,


включващ командата за изрязване и командата за поставяне , която илюстрира как да
смените реда на две колони в набор от данни. Можете също да изпълните тази задача
с помощта на командата awk (обсъдена в Глава 7 и Глава 9).
Machine Translated by Google

Има няколко точки, които трябва да имате предвид, преди да се задълбочите в подробностите за
скриптовете на обвивката. Първо, shell скриптовете могат да се изпълняват от командния ред след
добавяне на разрешения за „изпълнение“ към текстовия файл, съдържащ shell скрипта. Второ, можете
да използвате помощната програма crontab , за да планирате изпълнението на вашите скриптове на обвивката.
Помощната програма crontab ви позволява да зададете изпълнението на shell скрипт
на почасова, дневна, седмична или месечна база. Задачите, които обикновено се
планират чрез crontab, включват извършване на архивиране и премахване на
нежелани файлове. Ако сте съвсем нов в Unix, имайте предвид, че има начин да
изпълнявате скриптове както от командния ред, така и по „планиран“ начин.
Задаването на разрешения за файл за изпълнение на скрипта от командния ред ще бъде обсъдено п
Трето, съдържанието на всеки shell скрипт може да бъде просто като една команда
или може да включва стотици редове от bash команди. Като цяло по-интересните шел
скриптове включват комбинация от няколко bash команди. Съвет за учене: тъй като
обикновено има няколко начина за получаване на желания резултат, е полезно да
четете скриптове на обвивка на други хора, за да научите как да комбинирате команди
по полезни начини.

UNIX СРЕЩУ LINUX

Unix е операционна система, създадена от Кен Томпсън в началото на 70-те


години на миналия век и днес има няколко налични варианта, като HP/UX за машини
на HP и AIX за машини на IBM. Линус Торвалдс разработи операционната система
Linux през 90-те години и много команди на Linux са същите като техните копия на
bash (но съществуват разлики, често в командите за системни администратори).
Операционната система Mac OS X е базирана на AT&T Unix.

Unix има богата история и ако се интересувате от миналото му, можете да


прочетете онлайн статии, както и Wikipedia. Тази книга избягва тези подробности и се
фокусира върху това да ви помогне бързо да научите как да станете продуктивни с
различни команди.

Налични типове обвивки

Оригиналната обвивка на Unix е обвивката на Bourne, написана в средата на 70-


те години от Стивън Р. Борн. Обвивката на Bourne беше първата обвивка, която се
появи в bash системите и понякога ще чуете „черупката“ като препратка към обвивката
на Bourne. Bourne shell е POSIX стандартна обвивка, обикновено инсталирана
Machine Translated by Google

като /bin/sh на повечето версии на Unix, чиято подкана по подразбиране е знакът $ .


Следователно скриптовете на обвивката на Bourne ще се изпълняват на почти
всяка версия на Unix. По същество AT&T клоновете на Unix поддържат Bourne
shell (sh), bash, Korn shell (ksh), tsh и zsh.
Съществува обаче и BSD клон на Unix, който използва обвивката „C“ (csh), чиято
подкана по подразбиране е знакът % . По принцип шел скриптовете, написани за csh ,
няма да се изпълняват на AT&T клонове на Unix, освен ако csh шелът също не е
инсталиран на тези машини (и обратно).
Обвивката на Bourne е най-„неукрасената“ в смисъл, че й липсват някои команди,
които са налични в другите обвивки, като например history и noclobber. Различните
подкатегории за Bourne Shell са както следва:

• Bourne shell (sh) •


Korn shell (ksh) •
Bourne Again shell (bash) • POSIX
shell (sh) • zsh („Zee
shell“)

Различните обвивки тип C са както следва:

• C shell (csh) •
TENEX/TOPS C shell (tcsh)

Въпреки че командите и шел скриптовете в тази книга са базирани на bash шел,


много от командите работят и в други шел (и ако не, тези други шелове имат подобна
команда за постигане на същата цел). Извършването на търсене в Интернет за „как да
направя <команда bash> в <име на обвивката>“ често ще ви даде отговор. Понякога
командата е по същество същата, но с малко по-различен синтаксис и въвеждането на
„man <команда>“ в командна обвивка може да предостави полезна информация.

КАКВО Е BASH?

Bash е акроним за "Bourne Again Shell", който има своите корени в обвивката на
Bourne, създадена от Stephen R. Bourne. Shell скриптове, базирани на Bourne shell, ще
се изпълняват в bash, но обратното не винаги е вярно. Bash shell предоставя
допълнителни функции, които не са налични в Bourne shell, като поддръжка за масиви
(обсъдени по-късно в тази глава).
Machine Translated by Google

В Mac OS X директорията /bin съдържа следните изпълними обвивки:

-r-xr-xr-x 1 основно колело 1377872 28 април 2017 г. /bin/ksh -r-xr-xr-x 1 коренно


колело 630464 28 април 2017 г. /bin/sh -rwxr-xr-x 1 коренно колело 375632 28
април 2017 /bin/csh -rwxr-xr-x 1 основно колело 592656 28 април 2017 г. /bin/zsh -r-
xr-xr-x 1 коренно колело 626272 28 април 2017 г. /bin/bash

Сравнителна матрица на поддръжката за различни функции сред предходните черупки е


достъпна онлайн:

https://stackoverflow.com/questions/5725296/dif erence-between-sh-and-bash

В някои среди Bourne shell sh е bash shell, който можете да проверите, като напишете
следната команда:

sh --версия

Резултатът от предходната команда е както следва:

GNU bash, версия 3.2.57(1)-издаване (x86_64-apple-darwin16)


Copyright (C) 2007 Free Software Foundation, Inc.

Ако не сте запознати с командния ред (било то Mac, Linux или персонални компютри), моля,
прочетете Предговора, който предоставя някои полезни указания за достъп до командни
обвивки.

Получаване на помощ за bash команди

Ако искате да видите опциите за конкретна команда bash, извикайте


команда man , за да видите описание на тази команда bash и нейните опции:

мъж котка

Командата man създава кратки обяснения и ако тези обяснения не са достатъчно ясни,
можете да потърсите онлайн примерни кодове, които предоставят повече подробности.
Machine Translated by Google

Навигация из директории

В командна обвивка често ще извършвате основни операции, като показване


(или промяна) на текущата директория, извеждане на списък със съдържанието на
директория и показване на съдържанието на файл. Следният набор от команди ви
показва как да изпълнявате тези операции и можете да изпълните подмножество
от тези коментари в последователността, която е подходяща за вас. Опциите за
някои от командите в този раздел (като командата ls ) са описани по-подробно по-
късно в тази глава.
Често използвана команда bash е pwd („печат на работна директория“), която
показва текущата директория, както е показано тук:

pwd

Резултатът от предходната команда може да изглежда така:

/Потребители/jsmith

Използвайте командата cd („промяна на директория“), за да отидете до конкретна директория.


Например, въведете командата cd /Users/jsmith/Mail, за да отидете до тази
директория. Ако в момента сте в директорията /Users/jsmith , просто напишете cd
поща.

Можете да навигирате до началната си директория с една от тези команди:

$ cd $HOME $
cd

Един удобен начин за връщане към предишната директория е командата cd


-. Командата cd в Windows просто показва текущата директория и не променя
текущата директория (за разлика от командата cd на Unix ).

Командата на историята

Командата history показва списък (т.е. хронологията) на командите, които сте


изпълнили в текущата командна обвивка, както е показано тук:

история

Примерен изход от предходната команда е тук:


Machine Translated by Google

1202 cat longfile.txt > longfile2.txt 1203 vi longfile2.txt 1204 cat


longfile2.txt |fold -40 1205 cat
longfile2.txt |fold -30 1206 cat longfile2.txt |fold -50
1207 cat longfile2.txt |fold -45 1208 vi longfile2.txt 1209
история 1210 cd /Library/Developer/CommandLineTools/
usr/include/c++/ 1211 cd /tmp 1212 cd $HOME/Desktop
1213 история

Ако искате да отидете до директорията, която е показана в ред 1210, можете да го


направите просто като напишете следната команда:

!1210

Командата !cd ще търси назад в историята на командите, за да намери първата


команда, която съответства на командата cd . В този случай ред 1212 е първото
съвпадение. Ако няма намесващи се команди cd между текущата команда и командата
в ред 1210, тогава !1210 и !cd ще имат същия ефект.

ЗАБЕЛЕЖКА Внимавайте с “!” опция с bash команди, тъй като командата, която съответства на "!" може да

не е този, който възнамерявате. По-безопасно е да използвате командата history и след това изрично да

посочите правилния номер (в тази история), когато извикате "!" оператор.

ИЗВЕЖДАНЕ НА ФАЙЛОВИТЕ ИМЕНА С КОМАНДАТА LS

Командата ls е за изброяване на имена на файлове и има много налични


превключватели, които можете да използвате, както е показано в този раздел.
Например командата ls показва следните имена на файлове (реалният дисплей зависи
от размера на шрифта и ширината на командната обвивка) на моя MacBook:

apple-care.txt iphonemeetup.txt outfile.txt instructions.txt checkin-commands.txt ssl-


kyrgyzstan.txt output.txt
Machine Translated by Google

Командата ls -1 (цифрата “1”) показва вертикален списък с имена на файлове:

apple-care.txt checkin-
commands.txt

iphonemeetup.txt kyrgyzstan.txt
outfile.txt output.txt ssl-
instructions.txt

Командата ls -1 (буквата “l”) показва дълъг списък с имена на файлове:

общо 56

-rwx------ 1 персонал на ocampesato 25 януари 06 19:21 apple-care.txt -rwx------ 1 персонал на ocampesato 146 персонал на
ocampesato 146 януари 06 19:21 checkin-commands.txt

-rwx------ 1 ocampesato staff 478 6 януари 19:21 iphonemeetup.txt -rwx------ 1 ocampesato staff 12 6 януари 19:21 kyrgyzstan.txt -rw-
r--r-- 1 ocampesato staff 11 Jan 06 19:21 outfile.txt -rw-r--r-- 1 ocampesato staff 12 Jan 06 19:21 output.txt -rwx------ 1 ocampesato
staff 176 Jan 06 19:21 ssl -instructions.txt

Командата ls -1t (буквите „l“ и „t“) показва базиран на времето дълъг списък:

общо 56

-rwx------ 1 персонал на ocampesato 25 януари 06 19:21 apple-care.txt -rwx------ 1 персонал на ocampesato 146 персонал на
ocampesato 146 януари 06 19:21 checkin-commands.txt -rwx-- ---- 1 персонал на ocampesato 478 6 януари 19:21
iphonemeetup.txt

-rwx------ 1 персонал на ocampesato 12 6 януари 19:21 kyrgyzstan.txt -rw-r--r-- 1 персонал на ocampesato 11 ян 06 19:21 outfile.txt
-rw-r--r-- 1 персонал на ocampesato 12 януари 06 19:21 output.txt -rwx------ 1 персонал на ocampesato 176 6 януари 19:21 ssl-
instructions.txt

Командата ls -ltr (буквите „l“, „t“ и „r“) показват обърнато


базиран на времето дълъг списък с имена на файлове:

общо 56

-rwx------ 1 ocampesato staff 176 Jan 06 19:21 ssl-instructions.txt -rw-r--r-- 1 ocampesato staff 12 Jan 06 19:21
output.txt -rw-r--r -- 1 ocampesato

staff 11 януари 06 19:21 outfile.txt


Machine Translated by Google

-rwx------ 1 ocampesato staff 12 януари 06 19:21 kyrgyzstan.txt -rwx------ 1 ocampesato staff 478 Jan 06 19:21 iphonemeetup.txt
-rwx------ 1 ocampesato персонал 146 06 януари 19:21 checkin-commands.txt -rwx------ 1 ocampesato персонал 25 януари 06 19:21
apple-care.txt

Ето описанието на всички изброени колони в предходния изход:

Колона #1: представлява тип файл и разрешение, дадено за файла (вижте по-долу)
Колона #2: броят блокове памет, заети от файла или директорията
Колона #3: (bash потребител) собственик на файла
Колона #4: представлява групата на собственика
Колона #5: представлява размера на файла в байтове
Колона #6: датата и часа, когато този файл е създаден или последно модифициран

Колона #7: представлява име на файл или директория

В примера за списък с ls -l всеки файлов ред започва с d, - или l. Тези знаци показват типа
файл, който е в списъка. Тези (и други) първоначални стойности са описани по следния начин:

-
Обикновен файл (ASCII текстов файл, двоичен изпълним файл или твърда връзка)
b Блокирайте специален файл (като физически твърд диск)
Специален файл със знаци (като физически твърд диск)
Файл с директория, който съдържа списък с други файлове и директории.
cdl Файл със символна
стр връзка Наименуван канал (механизъм за комуникация между процесите)
с Гнездо (за комуникация между процесите)

Консултирайте се с онлайн документацията за повече подробности относно командата ls .

ПОКАЗВАНЕ НА СЪДЪРЖАНИЕТО НА ФАЙЛОВЕ

Този раздел ви запознава с няколко команди за показване на различни редове текст в


текстов файл. Преди да го направим, нека извикаме командата wc (броене на думи), за да
покажем броя на редовете, думите и знаците в текстов файл, както е показано тук:

wc longfile.txt 37 408 longfile.txt


80
Machine Translated by Google

Предходният резултат показва, че файлът longfile.txt съдържа 37 реда, 80 думи и 408


знака, което означава, че размерът на файла всъщност е доста малък (въпреки името му).

Командата на котката

Извикайте командата cat , за да покажете съдържанието на longfile.txt:

cat longfile.txt

Предходната команда показва следния текст:

съдържанието на този
дълъг файл

е твърде дълго,
за да се види на един
екран и на всеки ред

съдържа
едно или
повече думи и
ако използвате
котката
командвам
(другите редове са пропуснати)

Предходната команда показва съдържанието на файл; има обаче няколко команди, които
показват само част от файл, като по-малко, повече, страница, глава и опашка (всички те ще бъдат
обсъдени по-късно).
Като друг пример, да предположим, че файлът temp1 има следното
съдържание:

това е ред1 от temp1 това е ред2


от temp1 това е ред3 от temp1

Да предположим също, че файлът temp2 има следното съдържание:

това е ред1 от temp2 това е ред2


от temp2
Machine Translated by Google

Сега въведете следната команда, която съдържа ? мета символ (обсъден


подробно по-късно в тази глава):

котешка температура?

Резултатът от предходната команда е показан тук:

това е ред1 от temp1 това е ред2 от


temp1 това е ред3 от temp1 това е ред1
от temp2 това е ред2 от temp2

Главата и опашката команди

Командата head показва първите десет реда на текстов файл (по


подразбиране), пример за което е тук:

глава longfile.txt

Предходната команда показва следния текст:

съдържанието
от този

дълъг файл са
твърде дълги, за да
се видят в a

един екран и всеки ред


съдържа

едно или
повече думи

Командата head предоставя също опция за указване на различен номер


редове за показване, както е показано тук:

глава -4 дълъг файл.txt

Предходната команда показва следния текст:

съдържанието на това
Machine Translated by Google

дългите
файлове са твърде дълги

Командата tail показва последните 10 реда (по подразбиране) на текстов файл:

опашка longfile.txt

Предходната команда показва следния текст:

се предлага във всяка

обвивка, включително
обвивката bash

csh
zsh
кш
и обвивка на Борн

ЗАБЕЛЕЖКА Последните два реда в предходния резултат са празни редове (не са типографска
грешка на тази страница).

По същия начин командата tail ви позволява да зададете различен брой редове


за показване: tail -4 longfile.txt показва последните четири реда от
дълъг файл.txt.
Използвайте командата more , за да покажете пълен екран с данни, както е показано тук:

повече longfile.txt

Натиснете <интервал> , за да видите следващия екран с данни и натиснете


клавиша <return> , за да видите следващия ред текст във файл. Между другото, някои
хора предпочитат командата less , която генерира по същество същия резултат като
командата more .

Символът за тръба

Много полезна характеристика на bash е поддръжката на символа за тръба („|“) ,


който ви позволява да „пренасочвате“ или да пренасочвате изхода на една команда,
за да стане вход на друга команда. Командата pipe е полезна, когато искате да
изпълните последователност от операции, включващи различни bash команди.
Например, следният кодов фрагмент комбинира командата head
с командата cat и символа за тръба („|“) :
Machine Translated by Google

cat longfile.txt| глава -2

Техническа точка: предходната команда създава два bash процеса (повече за


процесите по-късно), докато командата head -2 longfile.txt създава само един bash
процес.
Можете да използвате командите head и tail по по-интересни начини. Например,
следната последователност от команди показва редове от 11 до 15 от
дълъг файл.txt:

глава -15 longfile.txt |опашка -5

Предходната команда показва следния текст:

и ако използвате
командата cat

съдържанието на файла
превъртане

Покажете номерата на редовете за предходния изход, както следва:

cat -n longfile.txt | глава -15 | опашка -5

Предходната команда показва следния текст:

11 и ако 12 използвате
котката
13 команда 14 съдържанието
на файла 15 превъртане

Няма да видите знака „tab“ от изхода, но той се вижда, ако пренасочите


предишната последователност от команди към файл и след това използвате опцията
„-t“ с командата cat :

cat -n longfile.txt | глава -15 | опашка -5 > 1 котка -t 1

11^И ако вие


12^Използвам котката
13^Аз командвам
14^Съдържание на файла
15^Iscroll
Machine Translated by Google

Командата за сгъване

Командата за сгъване ви позволява да „сгъвате“ редовете в текстов файл, което е


полезно за текстови файлове, които съдържат дълги редове текст, които искате да
разделите на по-къси редове. Ето например съдържанието на longfile2.txt:

съдържанието на този дълъг файл е твърде дълго, за да се види на един екран и всеки ред съдържа една
или повече думи и ако използвате командата cat, съдържанието на файла се превърта извън екрана, така че
можете да използвате други команди като глава или опашка или повече команди във връзка с командата pipe,
която е много полезна в Bash и е достъпна във всяка обвивка, включително обвивката на bash csh zsh ksh
и обвивката на Bourne

Можете да „сгънете“ съдържанието на longfile2.txt в редове, чиято дължина е 45


(само като пример) с тази команда:

cat longfile2.txt |сгъване -45

Резултатът от предходната команда е тук:

съдържанието на този дълъг файл е твърде дълго, за да се види на един екран и


всеки ред съдържа една или повече думи и ако използвате командата cat,
съдържанието на файла се превърта извън сипея

n така че можете да използвате други команди като h head или tail или повече команди
във връзка с командата pipe, която е много полезна в U nix и е налична във всяка
обвивка, включително bash shell csh zsh ksh и Bourne shell

Забележете, че някои думи в предходния изход са разделени въз основа на реда


ширина, а не „вестникарски стил“.
В глава 4 ще научите как да показвате редовете в текстов файл, които съответстват
на низ или модел, а в глава 5 ще научите как да замените низ с друг низ в текстов файл.

СОБСТВЕНОСТ НА ФАЙЛА: СОБСТВЕНИК, ГРУПА И СВЯТ

Bash файловете могат да имат частични или пълни rwx привилегии (където r е
привилегията за четене, w е привилегията за запис и x е привилегията за изпълнение,
което означава, че даден файл може да бъде изпълнен от командния ред) просто чрез
въвеждане на името на файла ( или пълния път до файла, ако файлът не е във вашия текущ
Machine Translated by Google

указател). Извикването на изпълним файл от командния ред ще накара операционната система


да се опита да изпълни команди в текстовия файл.
Използвайте командата chmod , за да зададете разрешения за файлове. Например, ако вие
трябва да зададете разрешението rwx rw- r-- за файл, използвайте следното:

chmod u=rwx g=rw o=r име на файл

В предходната команда опциите u, g и o представляват съответно потребителски разрешения,


групови разрешения и разрешения на други.
За да добавите допълнителни разрешения към текущия файл, използвайте + , за да добавите
разрешения към потребител, група или други, и използвайте -, за да премахнете разрешенията.
Например, даден файл с разрешения rwx rw- r--, добавете разрешението за изпълним
файл, както следва:

chmod o+x име на файл

Тази команда добавя x разрешение за други.


Добавете изпълнимото разрешение към всички категории разрешения (т.е. за a
потребител, група и други), както следва:

chmod a+x име на файл

В предходната команда буквата a означава „всички групи“. Обратно,


посочете - за премахване на разрешение от всички групи, както е показано тук:

chmod ax име на файл

СКРИТИ ФАЙЛОВЕ

Невидим файл е този, чийто първи знак е точката (.).

Bash програмите (включително обвивката) използват повечето от тези файлове за съхраняване


на конфигурационна информация. Някои често срещани примери за скрити файлове включват
следните файлове:

профил: Bourne shell (sh) инициализиращ скрипт bash_profile:


bash shell (bash) инициализиращ скрипт kshrc: Korn shell (ksh)
инициализиращ скрипт cshrc: C shell (csh) скрипт за
инициализиране
Machine Translated by Google

rhosts: конфигурационният файл на отдалечената обвивка

За да изброите невидимите файлове, задайте опцията -a за командата ls :

ls -a
. .профил .rhosts документи либ Резултати от тестовете
.. домакини потребители

.emacs bin hw1 кръчма рез.01 работа


.exrc ch07 hw2 res.02
.kshrc ch07.bak hw3 res.03

Единична точка .: Това представлява текущата директория.


Двойна точка ..: Това представлява родителската директория.

РАБОТА С ПРОБЛЕМНИ ИМЕНА НА ФАЙЛОВЕ

Проблемните имена на файлове съдържат един или повече интервали, скрити (непечатаеми)
знаци или започват с тире („-“).
Можете да използвате двойни кавички, за да изброявате имена на файлове, които съдържат интервали, или

можете да предхождате всяко празно пространство с обратна наклонена черта (“\”) .

Например, ако имате файл с име One Space.txt, можете да използвате ls


команда, както следва:

ls -1 "Едно пространство.txt"
ls -l One\ Space.txt

Имената на файлове, които започват с тире ("-"), са трудни за обработка


тъй като тире е префиксът, който указва опциите за bash
команди. Следователно, ако имате файл, чието име е -abc, тогава
командата ls -zbc няма да работи правилно, защото -z се интерпретира като a
превключете за командата ls (и няма опция „z“ ).
В повечето случаи най-доброто решение за този тип файл е да преименувате файла.
Това може да се направи във вашата операционна система, ако вашият клиент не е Unix shell,
или можете да използвате следния специален синтаксис за командата mv („преместване“).
преименувайте файла. Предходните две тирета казват на mv да игнорира тирето в
име на файл. Пример е тук:

mv -- -abc.txt преименуван-abc.txt
Machine Translated by Google

РАБОТА С ПРОМЕНЛИВИТЕ НА СРЕДАТА

Налични са много вградени променливи на средата и следващите подраздели


обсъждат командата env и след това някои от по-често срещаните променливи.

Командата env

Командата env ( „ среда“) показва променливите, които са във вашия


bash среда. Пример за изхода на командата env е тук:

SHELL=/bin/bash
TERM=xterm-256color
TMPDIR=/var/folders/73/39lngcln4dj_scmgvsv53g_w0000gn/T/ OLDPWD=/tmp

TERM_SESSION_ID=63101060-9DF0-405E-84E1-EC56282F4803 USER=ocampesato
COMMAND_MODE=bash2003PATH=/
o pt/local/bin:/Users/ocampesato/ android-sdk -mac_86/platform-tools:/Users/ocampesato/ android-sdk-mac_86/
tools:/usr/local/bin: PWD=/Users/ocampesato JAVA_HOME=/System/Library/Java/JavaVirtualMachines/
1.6.0.jdk/ Content ts/Home LANG=en_US.UTF-8 NODE_PATH=/usr/local/lib/
node_modules HOME=/Users/ocampesato
LOGNAME=ocampesato DISPLAY=/tmp/launch-xnTgkE/org.macosforge.xquartz:0 SECURITYSESSIONID=186a4

_=/usr/bin/env

Някои интересни примери за настройка на променлива на средата и изпълнение


на команда са описани онлайн:

https://stackoverflow.com/questions/13998075/setting-environment-
variable-for-one-program-call-in-bash-using-env

Полезни променливи на средата

Този раздел обсъжда някои важни променливи на средата, повечето от които


вероятно няма да е необходимо да променяте. Въпреки това е полезно да сте наясно
със съществуването на тези променливи и тяхната цел.
Machine Translated by Google

• Променливата HOME съдържа абсолютния път на домашната директория на


потребителя.
• Променливата HOSTNAME указва интернет името на хоста. •
Променливата LOGNAME указва потребителското име за вход. •
Променливата PATH указва пътя за търсене (вижте следващия подраздел). •
Променливата SHELL определя абсолютния път на текущата обвивка. • USER
указва текущото потребителско име на потребителя. Тази стойност може да е
различна от името за влизане, ако суперпотребител изпълни командата su , за да
емулира разрешенията на друг потребител.

Задаване на променливата на средата PATH

Програмите и другите изпълними файлове могат да съществуват в много директории,


така че операционните системи предоставят пътека за търсене, която изброява
директориите, където ОС търси изпълними файлове. Добавете директория към вашия
път, така че да можете да извикате изпълним файл, като посочите само името на файла.
Не е необходимо да посочвате пълния път до изпълнимия файл.
Пътят за търсене се съхранява в променлива на средата, която е именуван низ,
поддържан от операционната система. Тези променливи съдържат информация, достъпна
за командната обвивка и други програми.
Променливата на пътя се нарича PATH в bash или Path в Windows (bash е
малки и големи букви, но Windows не е).
Задайте пътя в bash/Linux:

експортиране PATH=$HOME/anaconda:$PATH

За да добавите директорията на Python към пътя за определена сесия в bash:

експортиране на PATH="$PATH:/usr/local/bin/python"

В Bourne shell или ksh shell въведете тази команда:

PATH="$PATH:/usr/local/bin/python"

ЗАБЕЛЕЖКА /usr/local/bin/python е пътят на директорията на Python .

Указване на псевдоними и променливи на средата


Machine Translated by Google

Следната команда дефинира променлива на средата, наречена h1:

h1=$HOME/тест

Сега въведете следната команда:

Ехо $h1

Ще видите следния изход на OS X:

/Потребители/jsmith/тест

Следващият кодов фрагмент ви показва как да зададете псевдонима на ll , така че


показва дългия списък на директория:

псевдоним ll="ls -l"

Следните три дефиниции на псевдоними включват командата ls и различни


ключове:

псевдоним ll="ls -l" псевдоним


lt="ls -lt" псевдоним ltr="ls -ltr"

Като пример, можете да замените командата ls -ltr (буквите „l“, „t“ и „r“), която
видяхте по-рано в главата, с псевдонима ltr и ще видите същия обърнат времеви
дълго списък с имена на файлове (възпроизведен тук):

общо 56

-rwx------ 1 ocampesato персонал 176 6 януари 19:21 ssl-instructions.txt

-rw-r--r-- 1 персонал ocampesato 12 януари 06 19:21 output.txt -rw-r--r-- 1 персонал ocampesato 11 януари 06 19:21
outfile.txt -rwx------ 1 ocampesato staff 12 Jan 06 19:21 kyrgyzstan.txt -rwx------ 1 ocampesato staff 478 Jan 06 19:21
iphonemeetup.txt -rwx------ 1 ocampesato staff 146 Jan 06 19:21 checkin -commands.txt -rwx------ 1 ocampesato staff 25 януари
06 19:21 apple-care.txt

Можете също така да дефинирате псевдоним, който съдържа символа bash pipe („|“):

псевдоним ltrm="ls -ltr|още"


Machine Translated by Google

По подобен начин можете да дефинирате псевдоними за команди, свързани с директория:

псевдоним ltd="ls -lt | grep '^d'" псевдоним


ltdm="ls -lt | grep '^d'|още"

НАМИРАНЕ НА ИЗПЪЛНИТЕЛИ ФАЙЛОВЕ

Има няколко налични команди за намиране на изпълними файлове (двоични файлове или
скриптове на обвивката) чрез търсене в директориите в променливата на средата PATH : which,
wheres , whereis и whatis. Тези команди дават подобни резултати като команда which , както е
обсъдено по-долу.
Командата which дава пълния път до изпълнимия файл, който посочите, или празен ред,
ако изпълнимият файл не е в никоя директория, която е посочена в променливата на средата
PATH . Това е полезно за намиране дали определена команда или помощна програма е
инсталирана в системата.

който rm

Резултатът от предходната команда е тук:

/bin/rm

Командата whereis предоставя информацията, която получавате от командата where :

$ където е rm /bin/
rm

Командата whatis търси указаната команда в базата данни whatis , което е полезно за
идентифициране на системни команди и важни конфигурационни файлове:

git-rm(1) от - премахване на файлове от работното дърво и


индекса grm(1), rm(1)

rm7(1), unlink(1) - премахване на файлове или директории -

премахване на записи в директория

Считайте го за опростена команда man , която показва кратки подробности за bash


командите (напр. въведете man ls и ще видите няколко страници от
Machine Translated by Google

обяснение относно командата ls ).

КОМАНДАТА PRINTF И КОМАНДАТА ECHO

Накратко, използвайте командата printf вместо командата echo , ако трябва да


контролирате изходния формат. Една ключова разлика е, че командата echo отпечатва
знак за нов ред, докато командата printf не отпечатва знак за нов ред. (Имайте това
предвид, когато видите командата printf в примерите на awk код в Глава 7.)

Като прост пример, поставете следния кодов фрагмент в шел скрипт:

printf "%-5s %-10s %-4s\n" ABC DEF GHI printf "%-5s %-10s %-4.2f\n" ABC
DEF 12.3456

Направете shell скрипта изпълним и след това стартирайте shell скрипта, след
което ще видите следния резултат:

АБВГДЕ GHI
АБВГДЕ 12.35 ч

Въведете следната двойка команди:

ехо "ABC DEF GHI" ехо "ABC DEF


12.3456"

Ще видите следния изход:

ABC DEF GHI


ABC DEF 12.3456

Подробна (и много дълга) дискусия относно оператора printf и командата echo е


достъпна онлайн:

https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-
echo

КОМАНДАТА ЗА РЯЗАНЕ

Командата cut ви позволява да извличате полета с определен разделител (друга


дума, често използвана за IFS, особено когато е част от
Machine Translated by Google

команден синтаксис, вместо да бъде зададен като външна променлива), както и


диапазон от колони от входен поток. Някои примери са тук:

x="abc def ghi" ехо $x |


изрязване -d" " -f2

Резултатът (използване на интервал " " като IFS и -f2 за обозначаване на втората
колона) на предходния кодов фрагмент е тук:

деф

Помислете за този кодов фрагмент:

x="abc def ghi" ехо $x |


изрежете -c2-5

Резултатът от предходния кодов фрагмент (-c2-5 означава „извличане на


знаци в колони от 2 до 5 от променливата”) е тук:

пр.н.е

Листинг 1.1 показва съдържанието на SplitName1.sh , което илюстрира как да


разделяне на име на файл, съдържащо „.“ символ като разделител/IFS.

ОБЯВКА 1.1: SplitName1.sh

име на файл="06.22.04p.vp.0.tgz"

f1=`echo $fileName | изрежете -d"." -f1` f2=`echo


$fileName | изрежете -d"." -f2` f3=`echo $fileName |
изрежете -d"." -f3` f4=`echo $fileName | изрежете -d"."
-f4` f5=`echo $fileName | изрежете -d"." -f5`

f5=`израз $f5 + 12`

newFileName="${f1}.${f2}.${f3}.${f4}.${f5}" echo "newFileName:


$newFileName"

Листинг 1.1 използва командата echo и командата cut за инициализиране на променливите f1, f2,
f3, f4 и f5, след което се конструира ново име на файл.
Резултатът от предходния шел скрипт е тук:
Machine Translated by Google

ново име на файл: 06.22.04p.vp.12

КОМАНДАТА ECHO И БЕЛИТЕ ПРОСТРАНСТВА

Командата echo запазва белите интервали в променливите, но в някои случаи


резултатите може да са различни от вашите очаквания.
Списък 1.2 показва съдържанието на EchoCut.sh , което илюстрира разликите,
които могат да възникнат, когато командата echo се използва с командата cut .

ОБЯВКА 1.2: EchoCut.sh

x1="123 456 789" x2="123 456


789" echo "x1 = $x1" echo
"x2 = $x2"

x3=`ехо $x1 | cut -c1-7` x4=`echo "$x1" |


cut -c1-7` x5=`echo $x2 | cut -c1-7` echo "x3
= $x3" echo "x4 = $x4" echo "x5 = $x5"

Стартирайте кода в листинг 1.2 и ще видите следния резултат:

x1 = 123 456 789


x2 = 123 456 789 x3 = 123
456 x4 = 123 4

x5 = 123 456

Стойността на x3 вероятно е различна от очакваната: има само едно празно място между 123 и 456

вместо трите празни интервала, които се появяват в дефиницията на променливата x1.

Този на пръв поглед незначителен детайл е важен, когато пишете шел скриптове,
които проверяват стойностите, съдържащи се в конкретни колони от текстови
файлове, като файлове за заплати и други файлове с финансови данни. Решението
включва използването на двойни кавички (а понякога и IFS променливата, която е
обсъдена в глава 2), която можете да видите в дефиницията на x4.
Machine Translated by Google

ЗАМЯНА НА КОМАНДАТА (ОБРАТНО)

Функцията за обратна отметка или заместване на команда на обвивката на Bourne е

мощна и ви позволява да комбинирате множество bash команди. Можете също така да


пишете компактни и мощни (и сложни) шел скриптове със заместване на команди.
Синтаксисът е просто да предхождате и следвате командата си със знака “'” (обратно). В
а листинг 1.2 командата за обратна отметка е 'ls *py'.

Листинг 1.3 показва съдържанието на CommandSubst.sh , илюстриращ подмножество


от списъка с файлове в директория.

ОБЯВКА 1.3: CommandSubst.sh

за f в `ls *py` do echo "file is: $f"

done

Листинг 1.3 съдържа for цикъл, който показва имената на файловете (в текущия
директория), които имат суфикс py .
Резултатът от списък 1.3 на моя MacBook е тук:

файлът е: файлът CapitalizeList.py е:


файлът CompareStrings.py е: файлът
FixedColumnCount1.py е: файлът
FixedColumnWidth1.py е: файлът
LongestShortest1.py е: файлът
My2DMatrix.pyβ е: файлът
PythonBash.py е: файлът
PythonBash2.py е : Файлът
StringChars1.py е: Файлът
Triangular1.py е: Файлът
Triangular2.py е: Zip1.py

ЗАБЕЛЕЖКА Резултатът зависи от това дали имате файлове с .py суфикс в директорията, където
изпълнявате CommandSubst.sh.

СИМВОЛЪТ НА ТРЪБА И МНОГО КОМАНДИ

На този етап сте виждали различни комбинации от bash команди, които са свързани с
„|“ символ. Освен това можете да пренасочите изхода към
Machine Translated by Google

файл. Общата форма изглежда така:

cmd1 | cmd2 | cmd3 …. >моят списък

Какво се случва, ако има междинни грешки? Видяхте как да пренасочвате съобщения
за грешка към /dev/null и можете също така да пренасочвате съобщения за грешка към
текстов файл, ако трябва да ги прегледате. Още една опция е да пренасочите stderr
(„стандартна грешка“) към stdout („стандартен изход“), което е извън обхвата на тази глава.

Може ли междинна грешка да доведе до повреда на целия „тръбопровод“?


За съжаление, обикновено е процес на проба и грешка за отстраняване на грешки в дълги
и сложни команди, които включват множество символи за тръба.
Помислете за случая, когато трябва да пренасочите изхода на множество команди към
едно и също място. Например следните команди показват изход на екрана:

ls | вид; echo "съдържанието на /tmp: "; ls /tmp

Можете лесно да пренасочите изхода към файл с тази команда:

(ls | sort; echo "съдържанието на /tmp:"; ls /tmp) > myfile1

Въпреки това всяка от предходните команди в скобите създава подобвивка (което е


допълнителен процес, който консумира памет и процесор). Можете да избегнете раждането
на подобвивки, като използвате {} вместо (), както е показано тук (и интервалът след { и
преди } е задължителен):

{ls | вид; echo "съдържанието на /tmp:"; ls /tmp } > myfile1

Да предположим, че искате да зададете променлива, да изпълните команда и да


извикате втора команда чрез канал, както е показано тук:

име=СМИТ cmd1 | cmd2

За съжаление, cmd2 в предходния кодов фрагмент не разпознава стойността на,


но има просто
име, решение, както е показано тук:

(име=SMITH cmd1) | cmd2


Machine Translated by Google

Използвайте символа двоен амперсанд && , ако искате да изпълните команда само
ако предишна команда е успешна. Например командата cd работи само ако командата
mkdir успее в следния кодов фрагмент:

mkdir /tmp2/abc && cd /tmp2/abc

Предходната команда ще бъде неуспешна, защото (по подразбиране) /tmp2 не


съществува. Въпреки това, следната команда е успешна, защото опцията -p гарантира, че
са създадени междинни директории:

mkdir -p /tmp/abc/def && cd /tmp/abc && ls -l

ИЗПОЛЗВАНЕ НА ТОЧКА И ЗАПЕТАЯ ЗА РАЗДЕЛЯНЕ НА КОМАНДИ

Можете да комбинирате няколко команди с точка и запетая („;“), както е показано тук:

cd /tmp; pwd; cd ~; pwd

Предходният кодов фрагмент навигира до директорията /tmp , отпечатва пълния път


до текущата директория, връща се към предишната директория и отново отпечатва
пълния път до текущата директория. Резултатът от предходната команда е тук:

/tmp
/Потребители/jsmith

Можете да използвате заместване на команда (обсъдено в следващия раздел), за да


присвоите изхода на променлива, както е показано тук:

x=`cd /tmp; pwd; cd ~; pwd` ехо $x

Резултатът от предходния фрагмент е тук:

/tmp /Потребители/jsmith

КОМАНДАТА PASTE
Machine Translated by Google

Командата за поставяне е полезна, когато трябва да комбинирате два файла по


„по двойки“. Например листинг 1.4 и листинг 1.5 показват съответно съдържанието на
текстовите файлове list1 и list2 . Можете да мислите за поставяне като третиране на
съдържанието на втория файл като допълнителна колона за първия файл. В нашия
първи пример първият файл има списък с файлове за копиране, а вторият файл има
списък с файлове, които са дестинацията за командата за копиране. След това Paste
обединява двата файла в изход, който може да бъде стартиран за изпълнение на
всички копие команди в една стъпка.

ЛИСТИНГ 1.4: списък1

cp abc.sh cp
abc2.sh cp
abc3.sh

СПИСЪК 1.5: списък 2

деф.ш
def2.sh
def3.sh

Листинг 1.6 показва резултата от извикването на следната команда:

поставете списък1 списък2 >списък1.sh

ЛИСТИНГ 1.6: list1.sh

cp abc.sh cp деф.ш

abc2.sh def2.sh cp abc3.sh


def3.sh

Листинг 1.6 съдържа три cp команди, които са резултат от извикване на


командата за поставяне . Ако искате да изпълните командите в листинг 1.6, направете
този скрипт на обвивката изпълним и след това стартирайте скрипта, както е показано тук:

chmod +x list1.sh ./list1.sh

Вмъкване на празни редове с командата paste


Machine Translated by Google

Вместо да обединявате два файла с еднаква дължина, пастата може да се използва и за добавяне
същото нещо за всеки ред във файл.
Да предположим, че текстовият файл names.txt съдържа следните редове:

Джейн Смит

Джон Джоунс

Дейв Едуардс

Следващата команда вмъква празен ред след всеки ред


names.txt:

поставете -d'\n' - /dev/null < names.txt

Резултатът от предходната команда е тук:

Джейн Смит
Джон Джоунс

Дейв Едуардс

Вмъкнете празен ред след всеки друг ред в names.txt с тази команда:

поставете -d'\n' - - /dev/null < names.txt

Резултатът е тук:

Джейн Смит
Джон Джоунс
Дейв Едуардс

Вмъкнете празен ред след всеки трети ред в names.txt с тази команда:

поставете -d'\n' - - - /dev/null < names.txt

Резултатът е тук:

Джейн Смит
Джон Джоунс
Дейв Едуардс

Имайте предвид, че има празен ред след третия ред в предходния изход.
Machine Translated by Google

ПРОСТ СЛУЧАЙ НА УПОТРЕБА С КОМАНДАТА PASTE

Примерният код в този раздел ви показва как да използвате командата paste за свързване на
последователни редове в набор от данни. Списък 1.7 показва съдържанието на line-pairs.csv , който
съдържа двойки букви и цифри, а листинг 1.8 съдържа reversecolumns.sh, който илюстрира как да
съпоставите двойките, въпреки че прекъсванията на редовете са на различни места между цифрите и
буквите.

ЛИСТИНГ 1.7: linepairs.csv

a,b,c,d,e,f,gh,i,j,k,l
1,2,3,4,5,6,7,8,9
10,11,12

ЛИСТИНГ 1.8: linepairs.sh

inputfile="linepairs.csv"
outputfile="linepairsjoined.csv"

# съединете двойки последователни редове:


поставете -d " " - - < $inputfile > $outputfile

# съединете три последователни реда: #paste


-d " " - - - < $inputfile > $outputfile

# съединете четири последователни реда:


#paste -d " " - - - - < $inputfile > $outputfile

Съдържанието на изходния файл е показано тук (обърнете внимание, че скриптът просто свързва
двойки редове и примерите за команди с три и четири реда са коментирани):

a,b,c,d,e,f,gh,i,j,k,l 1,2,3,4,5,6,7,8,9
10,11,12

Забележете, че предходният изход не е напълно правилен: има „ “ вместо „,” винаги, когато двойка
ревизия редове е съединена (между „g” интервал и „h” и „9 и 10”). Можем да направим необходимата
с помощта на командата sed (обсъдена в Глава 4):

cat $изходен файл | sed "s/ /,/g" > $outputfile2


Machine Translated by Google

Проверете съдържанието на $outputfile , за да видите резултата от предходния


кодов фрагмент.

ЛЕСЕН СЛУЧАЙ НА УПОТРЕБА С КОМАНДИ ЗА ИЗРЕЖАНЕ И ПОСТАВЯНЕ

Примерният код в този раздел ви показва как да използвате командите за изрязване


и поставяне , за да обърнете реда на две колони в набор от данни. Целта на shell скрипта
в листинг 1.10 е да ви помогне да придобиете известна практика за писане на bash
скриптове. По-доброто решение включва един ред код (показан в края на този раздел).

Списък 1.9 показва съдържанието на namepairs.csv , който съдържа първото име и


фамилията на набор от хора, а листинг 1.10 съдържа reversecolumns.sh, който илюстрира
как да обърнете тези две колони.

ЛИСТИНГ 1.9: namepairs.csv

Джейн, Смит
Дейв, Джоунс
Сара, Едуардс

ЛИСТИНГ 1.10: reversecolums.sh

inputfile="namepairs.csv"
outputfile="reversenames.csv" fnames="fnames"
lnames="lnames"

cat $inputfile|cut -d"," -f1 > $fnames cat $inputfile|cut -d"," -f2 >
$lnames

паста -d"," $lnames $fnames > $outputfile

Съдържанието на изходния файл $outputfile е показано тук:

Смит, Джейн
Джоунс, Дейв
Едуардс, Сара

Кодът в листинг 1.10 (след премахване на празни редове) се състои от седем реда
код, които включват създаване на два допълнителни междинни файла. Освен ако не се
нуждаете от тези файлове, добра идея е да премахнете тези два файла (което можете
да направите с една rm команда).
Machine Translated by Google

Въпреки че листинг 1.10 е ясен, има по-прост начин за изпълнение


на тази задача: използвайте командата cat и командата awk (обсъдени
подробно в Глава 7).
По-конкретно, сравнете съдържанието на reversecolumns.sh със
следния единствен ред код, който комбинира командата cat и командата
awk , за да генерира същия изход:

cat namepairs.txt |awk -F"," '{print $2 "," $1}'

Резултатът от предходния кодов фрагмент е тук:

Смит, Джейн
Джоунс, Дейв
Едуардс, Сара

Както можете да видите, има голяма разлика между тези две решения. Ако не сте
запознати с командата awk , тогава не бихте се сетили за второто решение. Въпреки
това, колкото повече научавате за bash командите и как да ги комбинирате, толкова
по-сръчни ще ставате по отношение на писането на по-добри скриптове на обвивката
за решаване на задачи за почистване на данни. Друг важен момент: документирайте
командите, когато стават по-сложни, тъй като могат да бъдат трудни за
интерпретиране по-късно от другите или дори от вас самите, ако е минало достатъчно
време. Коментар като следния може да бъде изключително полезен за тълкуване на код:

# Тази команда обръща имената и фамилиите в namepairs.txt cat namepairs.txt |awk -F","
'{print $2 "," $1}'

РАБОТА С МЕТАХАРАКТЕРИ

Метазнаците могат да се разглеждат като сложен набор от заместващи символи.


Регулярните изрази са „модел за търсене“, който е комбинация от нормален текст и
метасимволи. По концепция той много прилича на инструмент за „намиране“
(натиснете ctrl-f на вашата търсачка), но bash (и Unix като цяло) позволява много по-
сложно съпоставяне на шаблони поради богатия си набор от метазнаци. Има цели
книги, посветени на регулярните изрази, но този раздел съдържа достатъчно
информация, за да започнете, както и ключовите концепции, необходими за
манипулиране и почистване на данни.
Следните метазнаци са полезни с регулярни изрази:
Machine Translated by Google

• ? метасимволът се отнася до 0 или 1 срещания на нещо. • Метасимволът


+ се отнася до 1 или повече срещания на нещо. • Метазнакът * се отнася до
още 0 срещания на нещо.

Имайте предвид, че „нещо“ в предходните описания може да се отнася до цифра,


буква, дума или по-сложни комбинации.
Тук са показани някои примери, включващи метазнаци: Изразът a?
съвпада с низа a , а също и с низа a, последван от един знак, като a1, a2, …, aa, ab и ac.
Въпреки това, abc и a12 не отговарят на израза a?.

Изразът a+ съответства на низа a, последван от един или повече знака, като a1, a2, … , aa,
ab и ac (но abc и a12 не съвпадат).
Изразът a* съответства на низа a, последван от нула или повече знаци, като a, a1,
…, aa, ab и ac.
Тръбата „|“ метазнак (който има различен контекст от символа за тръба в
командния ред: регулярните изрази имат свой собствен синтаксис, който не съвпада
с този на операционната система през повечето време) предоставя избор от опции.
Например изразът a|b означава a или b, а изразът a|b|c означава a или b или c.

Метасимволът $ се отнася до края на ред от текст, а в регулярните изрази във vi


редактора метасимволът $ се отнася до последния ред във файла.

Метасимволът ^ се отнася до началото на низ или ред от текст.


Ето един пример:

*a$ съвпада с „Мери Анна“, но не и с „Анна Мери“


^A* съвпада с „Anna Mary“, но не и с „Mary Anna“

В случай на регулярни изрази, метасимволът ^ може също да означава „не


съвпада“. Следващият раздел съдържа някои примери за метасимвола ^ .

РАБОТА С ХАРАКТЕРНИ КЛАСОВЕ

Класовете знаци ви позволяват да изразите набор от цифри, букви или комбинация


от двете. Например, символният клас [0-9] съвпада с всяка една цифра; [az] съвпада с
всяка малка буква; и [AZ] съвпада с всеки
Machine Translated by Google

Главна буква. Можете също да посочите поддиапазони от цифри или букви, като
[3-7], [gp] и [FX], както и други комбинации:

• [0-9][0-9] съвпада с последователна двойка цифри


• [0-9[0-9][0-9] съвпада с три последователни цифри •
\d{3} също съвпада с три последователни цифри

Предишният раздел ви запозна с метасимвола ^ , а ето ги


някои примери за използване на ^ с класове знаци:

^[az] съвпада с всяка малка буква в началото на ред от текст ^[^az] съвпада
с всеки ред от текст, който не започва с малка буква

Въз основа на това, което сте научили досега, можете да разберете целта
от следните регулярни изрази:

([az]|[AZ]): или малка буква, или главна буква (^[az][az]): начална малка
буква, последвана от друга малка буква ^[^az][AZ]): нещо различно от
малка буква,
последвана от главна буква

Работа с “^” и “\” и “!”

Целта на знака ^ зависи от неговия контекст в регулярен израз. Например


следният израз съответства на текстов низ, който започва с цифра:

^[0-9]

Следният израз обаче съвпада с текстов низ, който не започва с цифра:

^[^0-9]

Така знакът ^ вътре в двойка съвпадащи квадратни скоби („[]”) отрича израза
непосредствено вдясно от него, който също е вътре в квадратните скоби.
Machine Translated by Google

Обратната наклонена черта ("\") ви позволява да "избягате" от значението на


метасимвол. Само за да поясня още малко: точка „.“ съвпада с един знак, докато
последователността "\." съответства на точката „.“ характер. Други примери са тук:

• \.H.* съответства на низа .Hello • H.*


съвпада с низа Hello • H.*\.
съответства на низа Hello. • .ell.
съвпада с низа Hello • .* съвпада с
низа Hello • \..* съвпада с
низа .Hello

! метазнак означава отрицание, както е показано тук:

• [! abc …] съответства на всеки знак, различен от посочените • [! a -


z ] съвпада с всеки знак, който не е в посочения диапазон

Глава 4 съдържа раздел, който обсъжда регулярни изрази, които комбинират


класове знаци и метасимволи, за да създадат сложни изрази за съпоставяне на сложни
низови модели (като имейл адреси).

Ами ZSH?

Най-новата версия на OS X предоставя zsh като обвивка по подразбиране вместо


обвивката bash. Можете да намерите директорията, която съдържа zsh , като въведете
тази команда:

който зш

и резултатът ще бъде

/bin/zsh

Bash и zsh имат някои общи функции, както е показано тук:

• z-команда •

автоматично
довършване •
автоматична корекция • персонализиране на цветовете
Machine Translated by Google

За разлика от zsh, обвивката bash няма вградено разширение със заместващи знаци.
Следователно довършването на табулатори в bash действа като изход на команда. Довършването
на табулатори в zsh прилича на „падащ“ списък, който изчезва, след като въведете допълнителни
знаци.

В допълнение, обвивката bash не поддържа префикс или постфикс команда


псевдоними. Сравнение на bash shell и zsh е достъпно онлайн:

https://sunlightmedia.org/bash-vs-zsh

Превключване между bash и zsh

Въведете следната команда, за да зададете zsh като обвивка по подразбиране в командна


обвивка:

chsh -s /bin/zsh
Превключете от zsh обратно към bash с тази команда:

chsh -s /bin/bash

Имайте предвид, че и двете предходни команди засягат само командната обвивка, където сте
стартирали командите.

Конфигуриране на zsh

Bash съхранява свързаните с потребителя конфигурационни настройки в скрития файл (във


вашата домашна директория) .bashrc, докато zsh използва файла .zshrc. Трябва обаче да създадете
последния файл, защото той не е създаден за вас.
Bash използва свързания с влизането файл .bash_profile, докато zsh използва
файла .zprofile (също във вашата домашна директория), който се извиква, когато влезете във
вашата система. Помислете за използването на конфигурационни мениджъри като Prezto или
Antigen, които да ви помогнат да зададете стойности на променливи. Извършете онлайн търсене
за повече подробности относно zsh.

РЕЗЮМЕ

Тази глава започна с въведение в някои обвивки на Unix, последвано от кратко обсъждане на
файлове, разрешения за файлове и директории. Освен това научихте как да създавате файлове и
директории и как да ги променяте
Machine Translated by Google

разрешения. След това научихте за променливите на средата, как да ги задавате и как да


използвате псевдоними. Освен това научихте за „извличането“ (наричано още „точкуване“)
на скрипт на обвивка и как това променя поведението на променливите от извикване на
скрипт на обвивка по нормалния начин.
След това научихте за командата за изрязване (за изрязване на колони и/или полета)
и командата за поставяне (за поставяне на тест заедно вертикално). Накрая видяхте два
случая на употреба, първият от които включваше командата за изрязване и командата за
поставяне , за да превключите реда към две колони в набор от данни. Вторият ви показа
друг начин за изпълнение на същата задача, като използвате концепции от по-късни
глави.
Machine Translated by Google

ГЛАВА 2

ФАЙЛОВЕ И ДИРЕКТОРИИ

T
неговата глава обсъжда файлове и директории и различни полезни bash
команди за тяхното управление. Ще научите как да използвате прости команди, които могат да
опростят задачите ви. В Глава 8 и Глава 9 ще научите как да създавате shell скриптове, включващи
някои от командите в тази глава, което допълнително ще намали времето, което отделяте за изпълнение
на рутинни задачи.

Първата част на тази глава показва работата с команди, свързани с файлове,


като touch, mv, cp и rm. Втората част на тази глава съдържа команди на shell за
управление на директории. Третата част на тази глава обсъжда метасимволи и
променливи, които можете да използвате, когато работите с файлове и скриптове
на обвивката.

СЪЗДАВАЙТЕ, КОПИРАЙТЕ, ПРЕМАХВАЙТЕ И ПРЕМЕСТВАЙТЕ ФАЙЛОВЕ

Този раздел обсъжда команди, свързани с файлове в bash, като touch, cp и rm , които ви позволяват

съответно да създавате, копирате и премахвате файлове. Следващите подраздели илюстрират как да


използвате тези удобни команди.
С изключение на раздела, който обсъжда как да създавате текстови файлове, другите раздели се отнасят
за текстови файлове, както и за двоични файлове.

Създаване на текстови файлове


Machine Translated by Google

Използвайте любимия си редактор (като vim, notepad++ и emacs), за да създадете


текстов файл. Ако предпочитате, създайте празен текстов файл чрез командата
докосване . Например следната команда илюстрира как да създадете празен файл,
наречен abc:

докоснете abc

Ако подадете командата ls -l abc, ще видите нещо подобно:

-rw-r--r-- 1 собственик персонал 0 2 юли 16:39 abc

Копиране на файлове

Можете да копирате файла abc (или всеки друг файл) в abc2 с тази команда:

cp abc abc2

Бъдете внимателни, когато използвате cp команда: ако целевият файл вече съществува,
уверете се, че наистина искате да презапишете съдържанието му с изходния файл.

Например и двете от следните команди копират файловете abc и abc2 в


директорията /tmp :

cp abc abc2 /tmp cp abc* /tmp

Въпреки това, следната команда замества файла abc2 със съдържанието на файла
abc:

cp abc*

Причината е проста: bash shell разширява предходната редовна команда.


израз преди изпълнението на cp Следователно, предходният cp
командата се „разширява“ до това команда: cp

cp abc abc2

За щастие можете да предотвратите презаписването на съществуващ файл от


друг файл с тази команда:
Machine Translated by Google

set -o noclobber

Сега, ако извикате по-ранната команда cp , ще видите следното съобщение за грешка:

bash: abc2: не може да презапише съществуващ файл

The cp предоставя няколко полезни превключвателя, които ви позволяват да


контролирате набора от файлове, които искате да копирате:

• флагът -a архив (за копиране на цяло дърво на директории) • флагът


за актуализиране -u (който предотвратява презаписването на по-нови файлове с идентични
имена) •
рекурсивните флагове -r и -R

Опцията -r е полезна за копиране на файлове и всички поддиректории на една директория


в друга директория. Например, следната команда копира файловете и поддиректориите (ако
има такива) от $HOME/abc в директорията
$HOME/def:

cd $HOME/abc . ../
cp -r def

Копиране на файлове със заместване на команда

Списък 2.1 показва съдържанието на CommandSubstCopy.sh , което илюстрира как да


използвате обратна отметка за копиране на набор от файлове в директория.

ЛИСТИНГ 2.1 CommandSubst.sh

mkdir текстови файлове

cp `ls *txt` текстови файлове

Предходната двойка команди създава директория текстови файлове в текущата директория


и след това копира всички файлове (разположени в текущата директория) със суфикс txt в
поддиректорията текстови файлове .

Тази команда няма да копира никакви поддиректории, които имат суфикс txt.
Ако искате да копирате файлове, които имат суфикс .txt, използвайте тази команда:
Machine Translated by Google

cp `ls *txt` текстови файлове

Друго предупреждение: ако имате директорията abc.txt или друга директория със суфикс .txt ,
тогава съдържанието на тази директория няма да бъде копирано (ще видите съобщение за грешка).
Следните команди също няма да успеят да копират съдържанието на abc.txt в текстовите файлове на
поддиректорията :

cp `ls -R *.txt` текстови файлове cp -r `ls


-R *.txt` текстови файлове

Извикайте следната команда, за да се уверите, че поддиректорията abc.txt е


копирана в поддиректорията текстови файлове :

cp -r abc.txt текстови файлове

Ако искате да копирате поддиректориите на abc.txt , но не и директорията abc.txt


в текстови файлове, използвайте тази команда:

cp -r abc.txt/* текстови файлове

Изтриване на

файлове Командата rm премахва файлове и когато зададете опцията -r , командата


rm премахва съдържанието на директория (както и директорията).
Например, премахнете файла abc с помощта на командата rm :

rm abc

Командата rm има някои полезни опции, като -r, -f и -i, които


представляват „рекурсивен“, „сила“ и „интерактивен“.
Можете да премахнете съдържанието на текущата директория и всички нейни
поддиректории с тази команда:

rm -rf *

ЗАБЕЛЕЖКА Бъдете много внимателни, когато използвате rm -rf * , за да не изтриете по невнимание


грешното дърво от файлове на вашата машина.
Machine Translated by Google

Опцията -i е удобна, когато искате да бъдете подканени преди изтриване на файл.


Преди да изтриете набор от файлове, използвайте командата ls , за да визуализирате
файловете, които възнамерявате да изтриете, като използвате командата rm . Например
изпълнете тази команда:

ls *.sh

Предходната команда ви показва файловете, които ще изтриете, когато изпълните тази


команда:

rm *.sh

По-рано в този раздел видяхте как да използвате заместване на команда, която


пренасочва изхода на една команда като вход на друга команда, за да копирате набор от
файлове. Като друг вариант, следната команда премахва файловете, които са изброени в
текстовия файл remove_list.txt , вместо да посочи списък с файлове от командния ред:

rm `cat remove_list.txt`

Ако има възможност (в някакъв момент в бъдещето), че може да имате нужда от някои
от файловете, които възнамерявате да изтриете, друга опция е да създадете директория и
да преместите тези файлове в тази директория, както е показано тук:

mkdir $HOME/backup-shell-scripts mv *sh $HOME/


backup-shell-scripts

Преместване на файлове

Командата mv е еквивалентна на комбинация от cp и rm. Можете да

използвате тази команда, за да преместите няколко файла в директория или дори да


преименувате директория. Когато се използва в неинтерактивен скрипт, mv поддържа
опцията -f (force) за заобикаляне на въвеждане от потребителя. Когато дадена директория
се премести в съществуваща директория, тя става поддиректория на целевата директория.

Командването

Командата ln ви позволява да създадете символна връзка към съществуващ файл,


което е предимство, когато съществуващият файл е голям, тъй като символният
Machine Translated by Google

връзката включва минимални допълнителни разходи. Освен това промените в


съществуващия файл са автоматично достъпни в символната връзка, което означава,
че можете да поддържате един файл като „източник на истината“, вместо да правите
същата актуализация на множество копия на файл.
Като прост пример, да предположим, че имате файл, наречен document1.txt във
вашата $HOME директория. Следната команда създава символна връзка, наречена
doc2, към файла document1.txt:

ln -s $HOME/document1.txt doc2

Ако извикате ls -l на doc2, ще видите нещо подобно:

lrwxr-xr-x 1 собственик персонал 26 февруари 8 10:57 doc2 -> /Users/owner/document1.txt

Ако премахнете doc2, това няма да засегне $HOME/document1.txt. Въпреки това, ако
премахнете последния файл, без да премахнете doc2, тогава doc2 ще продължи да се
показва в дълъг списък, но когато се опитате да видите съдържанието на doc2, файлът
е празен (както бихте очаквали).

КОМАНДИТЕ BASENAME, DIRNAME И FILE

Командите basename , dirname и file ви позволяват да намерите съответно


основната част от името на файла, частта от директорията и типа на файла.
Ето няколко примера:

$ x="/tmp/abcjs" $ базово име $x .js


$ abc

$ a="/tmp/a b.js" $ базово име


$a .js
а

b.js .js
$
базово име "$a" .js ab

$ dirname $x /tmp
Machine Translated by Google

$ файл /bin/ls
/bin/ls: Mach-O 64-битов изпълним x86_64

WC КОМАНДАТА

В глава 1 научихте как да използвате командата ls за получаване


информация за файловете в дадена директория. Можете да видите броя на
редове, думи и знаци в набор от файлове с помощта на командата wc . За
например, ако изпълните командата wc * в командна обвивка, ще видите
информация за всички файлове в директория, подобно на следния изход:

3 6 25 apple-care.txt
12 28 146 checkin-commands.txt
27 55 478 iphonemeetup.txt
12 kyrgyzstan.txt
21 12 11 outfile.txt
2 2 12 output.txt
11 176 ssl-instructions.txt
5 52 105 общо 860

Както можете да видите от последния ред в предишния изход, има общо


от 52 реда, 105 думи и 860 знака в текстовите файлове в тази директория. Ако
изпълните командата wc o*, ще видите информация за стартираните файлове
с буквата o, както е показано тук:

1 2 11 outfile.txt
2 2 12 output.txt
3 4 23 общо

Можете да преброите броя на файловете в директория с ls -1 |wc, as


показано тук:

7 7 112

Шел командите котка, повече, по-малко, главата и опашката са различни


части от файл. За кратки файлове тези команди могат да се припокриват по отношение на техните
изход. Следващите няколко раздела предоставят повече подробности за тях
команди, заедно с някои примери.

КОМАНДАТА НА КОТКАТА
Machine Translated by Google

Командата cat показва цялото съдържание на файл, което е удобно за малки файлове. За
по-дълги файлове можете да използвате командата more, която ви позволява да „листирате“
през съдържанието на файл.
Въведете командата

котка iphonemeetup.txt

за да видите следния изход:

iPhone среща
==============
* iPhone.WebDev.com
* iui.googlecode.com *
tinyurl.sqllite.com *
touchcode.googlecode.com: отворен код поддържа JSON

XCode: поддържа SVG-подобна функционалност

сайт на блог: iphoneinaction.manning.com

iPhone в действие: manning.com/callen

Лагер за разработчици на iPhone: вероятно лятото на 2021 г

openGL-ES как да:

* създаване на дъги/кръгове/елипси * линейни/


радиални градиенти
* Криви на Безие

* Urbanspoon срещу Yelp

Можете да видите атрибути, свързани с размера, с командата wc

iphonemeetup.txt:

21 48 417 iphonemeetup.txt

ПОВЕЧЕ КОМАНДА И ПО-МАЛКО КОМАНДА

Командата more ви позволява да преглеждате „страници“ със съдържание във файл.


Натиснете клавиша за интервал, за да преминете към следващата страница и натиснете
клавиша за връщане, за да преминете напред с един ред. Командата по-малко е подобна на
командата повече . Пример за командата more е тук:
Machine Translated by Google

още abc.txt

Като алтернатива можете да използвате този формуляр, но не забравяйте, че той е по-малко ефективен

защото участват два процеса:

котка abc.txt |още

Командата more съдържа някои полезни опции. Например, ако искате командата
more да започне от 15-ия ред във файл вместо от първия ред, използвайте тази
команда:

още +15 abc.txt

Ако даден файл съдържа няколко последователни празни реда, можете да ги премахнете
от изхода с тази команда:

повече -s abc.txt

Потърсете модела abc в текстов файл чрез следната команда:

още +/abc.txt

ГЛАВАТА КОМАНДАВА

Командата head ви позволява да покажете първоначален набор от редове, а числото по подразбиране е

10. Например следната команда показва първите три реда на test.txt:

котка test.txt |глава -3

Следната команда също показва първите три реда на test.txt:

глава -3 test.txt

Можете да покажете първите три реда на няколко файла. Следната команда показва първите три реда в

текстовия файл columns2.txt, columns3.txt и columns4.txt:

глава -3 колони [2-4].txt


Machine Translated by Google

Резултатът от предходната команда е тук:

==> columns2.txt <==


едно две
три четири
едно две три четири

==> columns3.txt <==


123 едно две 456 три
четири едно две три
четири

==> columns4.txt <== 123 ЕДНО ДВЕ


456 три четири

ЕДНО ДВЕ ТРИ ЧЕТИРИ

Следният кодов фрагмент проверява дали първият ред на test.txt съдържа низа
aa:

x=`cat test.txt |head -1|grep aa` if ["$x" != ""] echo "намерен aa в


първия ред" fi

Командата head показва първите 10 реда от файла, а командата tail показва


последните 10 реда от файла. Вместо да ви показваме резултата (който можете да
видите от предишния списък), нека комбинираме командите head и tail с командата
wc .
Следната команда комбинира командите head и wc :

глава iphonemeetup.txt |wc

Предходната команда показва следния резултат:

10 22 224

Можете също така да покажете съдържанието на файл, като всеки ред се


предхожда от номер на ред. Например командата комбинира командите cat и head :

cat -n iphonemeetup.txt |head -4

Предходната команда показва следния резултат:


Machine Translated by Google

1 iPhone среща 2 ==============


3 * iPhone.WebDev.com 4 *
iui.googlecode.com

КОМАНДАТА НА ОПАШКАТА

Командата tail ви позволява да показвате набор от редове в края на файл, а номерът по подразбиране

е 10. Например следната команда показва последните три реда на test.txt:

котка test.txt |опашка -3

Следната команда също показва последните три реда на test.txt:

опашка -3 test.txt

Можете да покажете последните три реда на множество файлове. Следната команда показва

последните три реда в текстовия файл columns2.txt, columns3.txt и columns4.txt:

опашка -3 колони[2-4].txt

Резултатът от предходната команда е тук:

==> columns2.txt <== пет шест едно


две три

четири пет

==> columns3.txt <== пет 123


шест
едно две три
четири пет

==> columns4.txt <==


пет 123 шест
едно две три четири
пет

Следният кодов фрагмент проверява дали първият ред на test.txt съдържа низа aa:
Machine Translated by Google

x=`cat test.txt |tail -1|grep aa` if ["$x" != ""]

echo "намерен aa в test.txt" fi

Следната команда показва три стойности:

опашка iphonemeetup.txt |wc 10


26 192

Първото число и в двата изходни списъка е 10, което потвърждава, че се показват само първите 10 реда или последните

десет реда. Обърнете внимание, че ако файлът съдържа 10 или по-малко реда, тогава изходът за глава, опашка, котка и

други е идентичен.

Можете да промените броя на редовете, които искате да видите в изхода на


командата head или командата tail . Например, командата показва три реда:

$ head -3 iphonemeetup.txt iPhone среща

==============

* iPhone.WebDev.com

Следващата команда последните три реда:

$ опашка -3 iphonemeetup.txt * Криви на Безие


* Urbanspoon срещу Yelp

Командата tail с опцията -f е полезна, когато имате продължителен процес, който


пренасочва изхода към файл. Да предположим например, че извиквате тази команда
от началната си директория:

намирам . -print |xargs grep -i abc >/tmp/abc &

Извикайте следната команда, за да видите съдържанието на файла /tmp/abc всеки


път, когато се актуализира:

опашка -f /tmp/abc

СРАВНЯВАНЕ НА ФАЙЛОВОТО СЪДЪРЖАНИЕ


Machine Translated by Google

Има няколко команди за сравняване на текстови файлове, като например cmp


команда и командата diff .
The cmp е по-проста версия на командата diff : diff отчита разликите между два
файла, докато cmp показва само в коя точка се различават.

ЗАБЕЛЕЖКА И diff , и cmp връщат състояние на излизане 0, ако сравняваните файлове са

идентични, и 1, ако файловете са различни, така че можете да използвате и двете команди в


тестова конструкция в рамките на скрипт на обвивка.

Командата comm е полезна за сравняване на сортирани файлове:

comm -опции първи файл втори файл

Командата comm file1 file2 извежда три колони:

• колона 1 = редове, уникални за file1 •


колона 2 = редове, уникални за file2 •
колона 3 = редове, общи за двата

Тези опции позволяват потискане на изхода на една или повече колони:

• -1 потиска колона 1 • -2
потиска колона 2 • -3 потиска
колона 3 • -12 потиска и двете
колони 1 и 2

Командата comm е полезна за сравняване на „речници“ или списъци с думи


съдържащ сортирани текстови файлове с по една дума на ред.

ЧАСТИТЕ ОТ ИМЕ НА ФАЙЛ

Командата basename „отстранява“ информацията за пътя от име на файл, като


отпечатва само името на файла. Основното име на конструкцията $0 е името на текущо
изпълняващия се скрипт. Тази функционалност може да се използва за съобщения за
„използване“, ако например се извика скрипт с липсващи аргументи:
Machine Translated by Google

echo "Използване: 'basename $0' arg1 arg2 … argn"

Командата dirname премахва основното име от име на файл, като отпечатва само
информацията за пътя.

ЗАБЕЛЕЖКА basename и dirname могат да работят с произволен низ. Не е необходимо аргументът да

препраща към съществуващ файл или дори да е име на файл.

Командата strings показва низове за печат (ако има такива) в двоичен файл или файл с
данни. Примерно извикване е тук:

низове /bin/ls

Първите няколко реда изход от предходната команда са тук:

$FreeBSD: src/bin/ls/cmp.c,v 1.12 2002/06/30 05:13:54 obrien Exp $ @(#) Copyright (c) 1989, 1993, 1994 The
Regents of the University of California. Всички права
запазени.
$FreeBSD: src/bin/ls/ls.c,v 1.66 2002/09/21 01:28:36 wollman Exp $ $FreeBSD: src/bin/ls/print.c,v 1.57
2002/08/29 14: 29:09 keramida Exp $ $FreeBSD: src/bin/ls/util.c,v 1.38 2005/06/03 11:05:58 dd Exp $ \\""

@(#)PROGRAM:ls ПРОЕКТ:file_cmds-264.50.1 КОЛОНИ

1@ABCFGHLOPRSTUWabcdefghiklmnopqrstuvwx bin/ls

Unix2003

РАБОТА С РАЗРЕШЕНИЯ ЗА ФАЙЛОВЕ

В предишен раздел използвахте командата докосване , за да създадете празно


файл abc и след това видя дългия му списък:

-rw-r--r-- 1 собственик персонал 0 2 ноември 17:12 abc

Всеки файл в bash съдържа набор от разрешения за три различни потребителски групи:
собственикът, групата и света. Наборът от разрешения за четене, запис и изпълнение, които
имат стойност съответно 4, 2 и 1, в основа 8 (осмична). По този начин разрешенията за файл
във всяка група могат да имат следното
Machine Translated by Google

стойности: 0 (няма), 1 (изпълнение), 2 (запис), 4 (четене), 5 (четене и изпълнение), 6 (четене


и запис) и 7 (четене, запис и изпълнение).
Например файл, чиито разрешения са 755, показват:

• Собственикът има разрешения за четене/запис/


изпълнение • Групата има разрешения за запис/
изпълнение • Светът има разрешения за запис/изпълнение

Можете да използвате различни опции с командата chmod , за да промените


разрешенията за файл.

Командата chmod

Командата chmod ви позволява да променяте разрешенията за файлове и директории.


Осмичното представяне 777 съответства на разрешенията, които позволяват четене,
rwxrwxrwx, писане и изпълнение и за трите групи. The
осмично представяне 644 съответства на разрешенията rw-r–r–.
Следната команда прави името на файла изпълнимо за всички потребители:

chmod +x име на файл

Имайте предвид, че следната команда прави файл изпълним само за собственика


на файла:

chmod u+x име на файл

Следната команда задава бита SUID (Set owner User ID) в разрешенията за име на
файл , което позволява на обикновен потребител да изпълни име на файл със същите
привилегии като собственика на файла (но не е приложимо за скриптове на обвивка):

chmod u+s име на файл

Следната команда прави името на файла годно за четене/запис от собственика


и може да се чете само от група и други:

chmod 644 име на файл

Следната команда прави името на файла само за четене за всички:


Machine Translated by Google

chmod 444 име на файл

Предоставете на всички разрешения за четене, писане и изпълнение в


директорията:

chmod 1777 име на директория

Отменете всички разрешения за директория (но не се налагат ограничения за


root потребителя):

chmod 000 име на директория

Глава 4 обсъжда как да използвате условна логика за проверка (и също така за промяна) на
разрешенията за файлове чрез скриптове на обвивката.

Промяна на собственика, разрешенията и групите

Командата chown ви позволява да променяте собствеността върху файлове и


директории. Например следната команда присвоява dsmith като собственик на
файловете със суфикс txt в текущата директория:

chown dsmith *txt

Командата chgrp променя групата от файлове и директории, както е показано тук:

chgrp вътрешен *.txt

В допълнение, командите chown и chgrp поддържат рекурсия чрез опцията -R ,


което означава, че командите могат да засегнат файлове, които са в поддиректория
на текущата директория.

Командите umask и ulimit

Всеки път, когато създавате файл в bash, променливата на средата umask съдържа
допълнението (база 8) на разрешенията по подразбиране, които са присвоени на този
файл. Можете да видите стойността на umask , като напишете тази команда в
командния ред и нейната типична стойност е 0022. Ако извършите (база 8) допълнение
на тази стойност, резултатът е 755.
Machine Translated by Google

Командата ulimit указва максималния размер на файл, който можете да създадете на


вашата машина. Когато извикате тази команда в командна обвивка, ще видите или
числова стойност, или думата unlimited.

РАБОТА С УКАЗАТЕЛНИЦИ

Директорията е файл, който съхранява имена на файлове и свързана информация .


Всички файлове (т.е. обикновени, специални или директория) се съдържат в директории.
Базираните на Unix файлови системи имат йерархична структура за организиране на
файлове и директории. Тази структура често се нарича дърво на директория. Дървото има
един коренов възел, знака за наклонена черта (/), и всички други директории се съдържат
под него. Позицията на всеки файл в йерархията се описва от името на пътя.

Елементите на името на пътя са разделени с наклонена черта (“/”). Името на пътя е


абсолютно, ако е описано във връзка с корена, така че абсолютните имена на пътища
винаги започват с /. Това са някои примери за абсолютни имена на файлове:

/etc/passwd /users/
oac/ml/class /dev/rdsk/Os5

Името на пътя може също да бъде относително към текущата ви работна директория.
Относителните имена на пътища започват с ./.

Абсолютни и относителни директории

Можете да навигирате до началната си директория с някоя от тези команди:

cd $HOME cd
~ cd

Имайте предвид, че в Windows командата cd ви показва текущата директория (тя не


навигира до началната директория).
Тилдът („~“) винаги показва начална директория. Ако искаш влизай
която и да е домашна директория на друг потребител, след това използвайте следната команда:

cd ~потребителско име
Machine Translated by Google

Можете да се върнете обратно към местоположението на директорията, преди да отидете


до текущата директория с тази команда:

cd -

Абсолютни/относителни имена на пътища

Директориите са подредени в йерархия с корен (/) в горната част. Позицията на всеки файл
в йерархията се описва с пълния му път.
Елементите на името на пътя са разделени с /. Името на пътя е абсолютно, ако е описано във
връзка с root, така че абсолютните имена на пътища винаги започват с /.
Ето няколко примера за абсолютни имена на файлове:

/etc/passwd /
users/oac/ml/class /dev/rdsk/
Os5

За да определите текущата си директория, използвайте командата pwd :

$ pwd

Резултатът ще бъде нещо подобно:

/Потребители/собственик/Изтегляния

Показване на съдържанието на директория с командата ls :

$ ls /usr/bin

Частичен списък на изхода от предходната команда е тук:

fc
fddist

fdesetup fg

fgrep
файл

Всички вградени изпълними файлове, които се обсъждат в тази книга, се намират в


/usr/bin директория.
Machine Translated by Google

Създаване на директории

Ако укажете няколко директории на командния ред, mkdir създава всяка от директориите.
Например следната команда създава директориите docs и pub като братя и сестри в текущата
директория:

mkdir docs pub

Сравнете предходната команда със следната команда, която създава тест на директорията и
данни от поддиректория в текущата директория:

mkdir -p тест/данни

Опцията -p принуждава създаването на липсващи междинни директории (ако има такива). Ако
междинна директория не съществува, mkdir издава съобщение за грешка. Да предположим
например, че акаунтът на междинната поддиректория не съществува в следния кодов фрагмент:

mkdir /tmp/accounting/test mkdir:


Неуспешно създаване на директория "/tmp/accounting/test";
няма такъв файл или директория

Можете също да използвате опцията -p , за да създадете поддиректория във вашата $HOME

директория, както е показано тук:

mkdir -p $HOME/a/b/c/нова-директория

Предходната команда създава следните поддиректории, в случай че някоя от тях не съществува:

$HOME/a
$HOME/a/b
$HOME/a/b/c
$HOME/a/b/c/нова-директория

Премахване на директории

По-рано научихте как да използвате rm -r за премахване на директория и нейното съдържание.


Можете също така да изтриете празни директории чрез командата rmdir , както следва:
Machine Translated by Google

rmdir dirname1

Можете да изтриете няколко празни директории наведнъж, както следва:

rmdir dirname1 dirname2 dirname3

Отново, предходната команда премахва директориите dirname1, dirname2 и dirname2 , ако са


празни. Командата rmdir не генерира резултат, ако е успешна.

Ако обаче има файлове в директорията dirname1 , можете да използвате или тази
команда

rm -r dirname1

или, алтернативно, можете първо да премахнете файловете в поддиректорията и след това да


премахнете самата директория, както е показано тук:

cd dirname1 rm
-rf * cd ../
rmdir
dirname1

Навигиране до директории

Използвайте командата cd , за да преминете към която и да е директория, като посочите валиден


абсолютен или относителен път. Синтаксисът е както следва:

cd dirname

Стойността на dirname е името на целевата директория. Например командата

cd /usr/local/bin

ще се промени в директорията

/usr/local/bin

Можете да промените директории, като използвате абсолютен път (както в предишния пример)
или чрез относителен път. Например, можете да превключите от това
Machine Translated by Google

директория към директорията /usr/home/jsmith чрез следния относителен път:

cd ../../home/jsmith

Файловата система е йерархична дървовидна система; следователно можете да навигирате


до родителска директория чрез синтаксиса с двойна точка (“../”). Можете също така да отидете до
родителската директория на текущата директория (и дори по-високо, ако има допълнителни
предшестващи директории), както е показано в предходния пример.

Преместване на директории

Командата mv (преместване) може също да се използва за преименуване на директория,


както и за преименуване на файл. Синтаксисът за преименуване на директория е същият като
преименуването на файл:

mv стар директор нов каталог

Въпреки това, ако целевата директория вече съществува и съдържа поне един
файл, тогава командата mv ще се провали, пример за което е тук:

mkdir /tmp/abcd докосване /


tmp/abcd/червено mkdir abcd mv
abcd /tmp

Тъй като директорията /tmp/abcd не е празна, ще видите следното съобщение за


грешка:

mv: преименувайте abcd на /tmp/abcd: Директорията не е празна

По същество bash предоставя функция „noclobber“ за непразно


директории, което ви предпазва от презаписване на съществуващ файл.

ИЗПОЛЗВАНЕ НА ЗНАЦИ В ЦИТАТИ

Има три вида кавички: единични кавички ('), двойни кавички (“) и обратни кавички (`), които
се срещат в съвпадащи двойки ('', “”, или ``).
Въпреки че тези знаци за кавички може да изглеждат взаимозаменяеми, има някои разлики.
Machine Translated by Google

Единичните кавички не позволяват на обвивката да замени аргумента със


стойността на променлива на обвивката. Знаците в двойка единични кавички се
тълкуват буквално, което означава, че техните значения на метасимволи (ако има
такива) се игнорират. По същия начин, обвивката не замества препратките към
обвивката или променливите на средата със стойността на реферираната променлива.
Знаците в двойка двойни кавички се тълкуват буквално: значенията на техните
метасимволи (ако има такива) се игнорират. Обвивката обаче заменя препратките
към променливите на обвивката или средата със стойността на реферираната
променлива.
Текстът в двойка обратни кавички се интерпретира като команда, която обвивката
изпълнява, преди да изпълни останалата част от командния ред. Резултатът от
командата замества оригиналния обратно цитиран текст.
В допълнение, метасимволът се третира буквално винаги, когато е предшестван
от обратната наклонена черта (\).
Следните примери илюстрират разликите, когато използвате различни знаци за
кавички:

ехо $PATH

Командата echo ще отпечата стойността на променливата на обвивката PATH .


Въпреки това, като затворите аргумента в единични кавички, получавате желания
резултат:

ехо '$PATH'

Двойните кавички имат подобен ефект. Те предпазват черупката от


„глобиране“ на име на файл, но разрешаване на разширяването на променливите на обвивката.

Силата на обратните кавички е способността да се изпълни команда и да се


използва нейният изход като аргумент на друга команда. Например следната команда
показва броя на файловете в домашната директория на потребителя:

echo Моята домашна директория съдържа `ls ~ | wc -l` файлове.

Предходната команда първо изпълнява командата, съдържаща се в обратни


кавички:

ls ~ | wc -л
Machine Translated by Google

За целите на илюстрацията, нека приемем, че предходната команда показва стойността 22.


Тогава по-ранната команда echo показва следния изход:

Моята домашна директория съдържа 22 файла.

ПОТОЦИ И КОМАНДИ ЗА ПРЕНАСОЧВАНЕ

Числата 0,1 и 2 имат специално значение, когато 0 се предхожда от символа „<“, а също и
когато числата 1 и 2 са последвани от символа „>“, без интервали между цифрата 0 и „< ” и без
интервали между цифрите 1 и 2 и „>.”

В тази ситуация 0 се отнася за стандартен вход (stdin), 1 се отнася за стандартен изход (stdout)
и 2 се отнася за стандартна грешка (stderr). Моделът 1>file1 и 2>file2 ви позволява да пренасочвате
изход от изпълним файл.
В допълнение, „директорията“ /dev/null се отнася до кофата с нулеви битове и всичко, което
пренасочвате към тази директория, по същество се изхвърля. Тази конструкция е полезна, когато
искате да пренасочите съобщение за грешка, което може безопасно да бъде игнорирано.

Ето няколко примера:

котка $abc 1>std1 2>std2

Можете да пренасочите стандартната грешка към стандартния изход и след това


пренасочете последния към един файл, както е показано тук:

котка $abc 2>&1 1>std1

Можете да пренасочите изхода на bash командите по различни начини,


в зависимост от вашите нужди, както е показано тук:

cmd > myfile cmd >> пренасочва изхода на cmd към myfile
myfile cmd < myfile cmd добавя изхода на cmd към myfile изпраща съдържанието на
1>out1 2>out2 myfile към cmd
изпраща stdout към out1 и stderr към out2
cmd 2>&1 1>onefile1 изпраща stdout и stderr към onefile1

Можете също така да пренасочвате съобщенията за грешка към /dev/null, което означава, че вие
никога няма да видите тези съобщения за грешка.
Machine Translated by Google

Например, ако се опитате да изброите съдържанието на несъществуващото


директория /temp, ще видите това съобщение за грешка:

ls: /temp: Няма такъв файл или директория

Можете обаче да потиснете предходното съобщение за грешка с тази команда:

ls /temp 2>/dev/null

Можете да пренасочите стандартния изход и стандартната грешка към един и същи


файл с тази команда:

ls /temp 1>output1.txt 2>&1

В предходния кодов фрагмент файлът output1.txt съдържа същото съобщение за


грешка.
Имайте предвид, че следната команда показва съобщението за грешка на екрана
(забележете различното местоположение на 2>&1):

ls /temp 2>&1 1>output1.txt

ЗАБЕЛЕЖКА Пренасочвайте съобщенията за грешка към /dev/null само ако сте сигурни, че могат
безопасно да бъдат игнорирани.

Пренасочването може да бъде удобно във връзка с командата find as


както и поредици от команди, които са свързани със символа за тръба.

МЕТАХАРАКТЕРИ И КЛАСОВЕ ХАРАКТЕРИ

Както видяхте в глава 1, bash поддържа метасимволи, както и регулярни изрази. Ако
сте работили със скриптов език като Perl или езици като JavaScript и Java, несъмнено сте
срещали метасимволи. Ето разширен списък с метасимволи, които bash shell поддържа:

? (0 или 1): * (0 а? съвпада с низ a (но не ab) a* съвпада с низ aaa (но
или повече): + (1 или не baa) a+ съвпада с aaa (но не baa)
повече):
Machine Translated by Google

^
(начало на ред): ^[a] съвпада с низа abc (но не bc) $ (край на реда): [c]$ съвпада с низа abc (но не и cab) .
(единична точка): съответства на всеки знак (с изключение на нов ред)

Предходните метасимволи могат да се използват в bash с команди като ls и


sed, в шел скриптове и в редактори като vi (но има някои фини разлики в
интерпретацията на метасимволите).

Цифри и знаци

Следните кодови фрагменти илюстрират как да зададете поредици от цифри


и последователности от символни низове:

• [0-9] съвпада с една цифра •


[0-9][0-9] съвпада с 2 последователни цифри
• ^[0-9]+$ съвпада с низ, състоящ се само от цифри

Можете да дефинирате подобни модели, като използвате главни или малки букви:

[az] съвпада с една малка буква


[AZ] съвпада с една главна буква
[az][AZ] съвпада с една малка буква, последвана от 1 главна буква
съвпада с всяка
[a-zA-Z] главна или малка буква

ИМЕНА НА ФАЙЛОВЕ И МЕТАХАРАКТЕРИ

Преди обвивката да предаде аргументи на външна команда или да интерпретира


вградена команда, тя сканира командния ред за определени специални знаци и
изпълнява операция, известна като „globbing“ на името на файла. Вече видяхте някои
метасимволи в един ранен раздел и този раздел ви показва как да ги използвате с
командата ls .

ls -l файл1 файл2 файл3 файл04

Въпреки това, следната команда отчита същата информация и е много по-


бърза за въвеждане:

ls -l файл*
Machine Translated by Google

Да предположим, че сте издали следната команда:

ls -l файл?

? метасимволът на името на файла може да съответства само на един знак.


Следователно file04 няма да се появи в изхода на командата. По същия начин командата
показва само file2 и file3:

$ ls -l файл [2-3]

Файловете file2 и file3 са единствените файлове, чиито имена отговарят на посочения


шаблон, който изисква последният знак от името на файла да бъде в диапазона 2-3.

Можете да използвате повече от един метасимвол в един аргумент. Например, разгледайте


следната команда:

ls -l файл??

Повечето команди ви позволяват да посочите множество аргументи. Ако нито един файл
не съответства на даден аргумент, командата игнорира аргумента. Ето друга команда, която
отчита и четирите файла:

ls -l файл0* файл[1-3]

Да предположим, че една команда има един или повече аргументи, които включват един
или повече метасимволи. Ако нито един от аргументите не съвпада с имена на файлове,
обвивката предава аргументите на програмата с непокътнати метасимволи. Когато програмата
очаква валидно име на файл, може да възникне неочаквана грешка.
Друг метазнак ви позволява лесно да препращате към началната си директория. За
Например, следната команда изброява файловете в домашната директория на потребителя:

ls ~

РЕЗЮМЕ

Тази глава започна с обяснение на файловите разрешения за файлове и директории и как да ги зададете според

вашите изисквания. След това научихте за набор от команди, свързани с файлове, включително командите touch, mv, cp и rm.
Machine Translated by Google

След това видяхте някои bash команди за управление на директории и тяхното


съдържание. Най-накрая научихте повече подробности за метасимволите и променливите,
които можете да използвате, когато работите с файлове и скриптове на обвивката.
Machine Translated by Google

ГЛАВА 3

ПОЛЕЗНИ КОМАНДИ

неговата глава обсъжда bash команди за манипулиране на съдържанието на текстови T файлове,


както и търсене на низове в текстови файлове с помощта на командата bash “pipe”, която пренасочва
изхода на една bash команда като вход на втора bash команда.

Първата част на тази глава ви показва как да обединявате, сгъвате и разделяте текстови файлове.
Този раздел също така ви показва как да сортирате файлове и да намирате уникални редове във
файлове, като използвате съответно командите sort и uniq . Последната част обяснява как да сравнявате
текстови файлове и двоични файлове.
Вторият раздел ви запознава с командата find , която е мощна команда, която поддържа много
опции. Например, можете да търсите файлове в текущата директория или в поддиректории и можете
да търсите файлове въз основа на датата на тяхното създаване и датата на последна промяна. Една
удобна комбинация е да „пренасочите“ изхода от командата find към командата за търсене на файлове
за конкретен модел. След това ще видите как да използвате
xargs командата tr , инструмент, който обработва
много често използвани текстови трансформации, като изписване с главни букви или премахване на
интервали. След раздела, който обсъжда командата tr , ще видите случай на употреба, който ви показва
как да използвате командата tr , за да премахнете контролния знак ^M от набор от данни.

Третият раздел съдържа команди, свързани с компресията, като cpio, tar и bash команди за управление
на файлове, които вече са компресирани (като и zmore). zdiff, zcmp, Четвъртият раздел ви запознава с
която е полезна, опцията IFS ,
когато трябва да посочите разделител на полето, който не е по подразбиране, докато извличате данни
от диапазон от колони в набор от данни. Ще видите също как да използвате командата за „line
xargs
нагоре“ колоните на набор от данни, така че всички редове да имат еднакъв брой колони.
Machine Translated by Google

Петият раздел ви показва как да създавате shell скриптове, които съдържат bash
команди, които се изпълняват последователно.

КОМАНДАТА JOIN

Командата за присъединяване ви позволява да обедините два файла по смислен начин,


което по същество създава проста версия на релационна база данни.
Командата за присъединяване работи с два файла; той поставя заедно само онези редове
с общо етикетирано поле (обикновено цифров етикет) и записва резултата в stdout. Файловете,
които ще се съединяват, трябва да бъдат сортирани според полето с етикети, за да работят
правилно съвпаденията. Листинг 3.1 и листинг 3.2 показват съответно съдържанието на 1.data
и 2.data .

ОБЯВКА 3.1: 1.данни

100 Обувки
200 връзки
300 чорапи

ОБЯВКА 3.2: 2.данни

100 40,00 $ 200


1,00 $ 300 2,00 $

Сега стартирайте следната команда от командния ред:

присъединяване към 1.данни 2.данни

Предходният кодов фрагмент генерира следния изход:

100 обувки 40,00 $ 200 връзки


1,00 $ 300 чорапи 2,00 $

КОМАНДАТА ЗА СГЪВАНЕ

Командата за сгъване ви позволява да показвате набор от редове с фиксирана ширина на


колоната и този раздел съдържа още няколко примера. Обърнете внимание, че тази команда
не взема предвид интервалите между думите: изходът се показва в колони, които приличат на
стил „вестник“.
Следната команда показва набор от редове с десет знака във всеки ред:
Machine Translated by Google

x="aa bb cc defghij kk ll mm nn" echo $x |fold -10

Резултатът от предходния кодов фрагмент е тук:

aa bb cc defghij kk

ll m

m nn

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

x="Бързата кафява лисица прескача дебелото мързеливо куче." echo $x |


сгъване -10

Резултатът от предходния кодов фрагмент е тук:

Бързата кафява
лисица прескача

дебелото лудо куче.

КОМАНДАТА НА РАЗДЕЛЯНЕТО

Командата split е полезна, когато искате да създадете набор от подфайлове на даден файл. По
подразбиране подфайловете са именувани и xzz. Така xaa, xab, …, xaz, xba, xbb, …, xbz,
по подразбиране за командата за разделяне създава максимум 676 … xza, xzb, … файла (=26x26). Размерът

всеки от тези файлове е 1000 реда.


Следният фрагмент илюстрира как да извикате командата split , за да разделите файла
abc.txt на файлове с 500 реда всеки:

разделяне -l 500 abc.txt

Ако файлът abc.txt съдържа между 501 и 1000 реда, тогава предходната команда ще
създаде следната двойка файлове:

xaa
xab

Можете също така да посочите файлов префикс за създадените файлове, както е показано тук:

split -l 500 abc.txt по-кратък


Machine Translated by Google

Предходната команда създава следната двойка файлове:

по-краткоxaa
по-кратъкxab

КОМАНДАТА ЗА СОРТИРАНЕ

Командата sort сортира редовете в текстов файл. Например, да предположим, че вие


имате текстов файл, наречен test2.txt , който съдържа следните редове:

аа
вв
bb

И двете от следните команди ще сортират редовете в test2.txt:

cat test2.txt | сортиране сортиране


test2.txt

Резултатът от предходните команди е тук:

аа
bb
вв

Командата сортиране подрежда редове от текст по азбучен ред по подразбиране. някои


опциите за командата sort са тук:


-n Сортиране по числа (10 ще сортира след 2), игнориране на празни места и
• раздели -r Обръщане на реда на

сортиране • -f Сортиране на главни и малки букви



заедно +x Игнориране на първите x полета при сортиране

Можете да използвате командата за сортиране , за да покажете файловете в директория, базирана на


техния файлов размер, както е показано тук:

-rw-r--r-- 1 ocampesato персонал -rw-r--r-- 1 ocampesato 11 април 06 19:21 outfile.txt 12 април 06 19:21
персонал -rwx------ 1 ocampesato персонал 25 април 06 г. output.txt
19:21 apple-care.txt -rwx-- ---- 1 ocampesato staff 146 Apr 06 19:21 checkin-commands.txt -rwx------ 1 ocampesato staff 176 Apr 06
19:21 ssl-instructions.txt -rwx------ 1 ocampesato персонал 417 апр 06 19:43 iphonemeetup.txt
Machine Translated by Google

Командата за сортиране поддържа много опции, някои от които са обобщени тук.

Командата sort -r сортира списъка с файлове в обратен хронологичен ред.


Командата sort -n сортира по числови данни, а командата sort -k сортира по поле. Например следната

команда показва дългия списък на файловете в директория, които са сортирани по техния файлов
размер:

ls -l | сортиране -k 5

Резултатът е тук:

общо 72 -rw-r--

r-- 1 ocampesato staff 12 април 06 20:46 output.txt -rw-r--r-- 1 ocampesato staff 14 април 06 20:46 outfile.txt -rwx---- --
1 персонал на ocampesato 25 април 06 20:46 apple-care.txt -rwxr-xr-x 1 персонал на ocampesato 90 април 06 20:50
testvars.sh -rwxr-xr-x 1 персонал на ocampesato 100 април 06 20:50 testvars2 .sh -rwx------ 1 ocampesato staff 146 Apr 06
20:46 checkin-commands.txt -rwx------ 1 ocampesato staff 176 Apr 06 20:46 ssl-instructions.txt -rwx-- ---- 1 ocampesato
staff 417 6 април 20:46 iphonemeetup.txt

Забележете, че списъкът с файлове е сортиран въз основа на петата колона, която показва
размера на всеки файл. Можете да сортирате файловете в директория и да ги показвате от най-
големия до най-малкия с тази команда:

ls -l | сортиране -n

В допълнение към сортирането на списъци с файлове, можете да използвате командата за


сортиране , за да сортирате съдържанието на файл. Да предположим например, че файлът abc2.txt
съдържа следното:

Това е първи ред


Това е втори ред
Това е първи ред
Това е ред три
Четвърти ред
Пети ред
Шестият ред
Седмият ред

Следната команда сортира съдържанието на abc2.txt:

сортирайте abc2.txt

Можете да сортирате съдържанието на множество файлове и да пренасочите изхода към друг


файл:
Machine Translated by Google

sort outfile.txt output.txt > sortedfile.txt

Пример за комбиниране на командите sort и tail е показан тук:

котка abc2.txt | сортиране | опашка -5

Предходната команда сортира съдържанието на файла abc2.txt и след това


показва последните пет реда:

Седмият ред
Шестият ред
Това е първи ред
Това е първи ред
Това е ред три
Това е втори ред

Както можете да видите, предходният изход съдържа два дублиращи се реда. Следващият
разделът ви показва как да използвате командата uniq за премахване на дублиращи се редове.

УНИКАЛНАТА КОМАНДА

Командата uniq отпечатва само уникалните редове в сортиран текстов файл (т.е. игнорира
дублиращи се редове). Като прост пример, да предположим, че файлът test3.txt съдържа
следния текст:

абв
деф
абв
абв

Следната команда сортира съдържанието на test3.txt и след това показва уникалните


редове:

котка test3.txt | сортиране | уникален

Резултатът от предходния кодов фрагмент е тук:

абВ
ГДЕ

КАК ДА СРАВНЯВАТЕ ФАЙЛОВЕ

Командата diff ви позволява да сравнявате два текстови файла, а командата сравнява cmp
два двоични файла. Да предположим например, че файлът
Machine Translated by Google

output.txt съдържа тези два реда:

Здравейте

Свят

Да предположим, че файлът outfile.txt съдържа тези два реда:

сбогом свят

Тогава изходът на тази команда

diff output.txt outfile.txt

е показано тук:

1,2c1,2
< Здравейте
< Свят
---

> сбогом > свят

Обърнете внимание, че командата diff извършва чувствително към малки и главни букви текстово сравнение,

което означава, че низовете Hello и hello се третират като различни низове.

КОМАНДАТА OD

Командата od показва осмичен дъмп на файл, който може да бъде много полезен, когато искате да видите

вградени контролни знаци (като символи за табулация), които обикновено не се виждат на екрана. Тази команда

съдържа много превключватели, които можете да видите, когато въведете man od.

Като прост пример, да предположим, че файлът tabs.txt съдържа един ред текст
със следните три букви, разделени с табулатор (който не се вижда тук) между всяка
двойка букви:

а b °С

Следната команда показва табулатора и знаците за нов ред във файла


abc.txt:

cat tabs.txt |od -tc

Предходната команда генерира следния изход:


Machine Translated by Google

0000000 a \tb \tc \n


0000006

В специалния случай на раздели, друг начин да ги видите е да използвате следната


команда cat :

котка -t abc.txt

Резултатът от предходната команда е тук:

a^Ib^Ic

В глава 1 научихте, че командата echo отпечатва знак за нов ред, докато командата
printf не отпечатва знак за нов ред (освен ако не е изрично включен). Можете сами да
проверите този факт с този кодов фрагмент:

ехо abcde | od -c 0000000 ab


0000006 printf abcde | od -c °С de \n
0000000 ab

0000005
°С де

КОМАНДАТА TR

Командата tr е универсална команда, която поддържа някои полезни опции.


Например, командата tr ви позволява да премахвате излишни празни интервали в набори
от данни, да вмъквате празни редове, да отпечатвате думи на отделни редове и да
превеждате знаци от един набор от знаци в друг набор от знаци (т.е. от главни към малки
букви и обратно).
Следната команда прави всяка буква в променливата x с главна буква:

x="abc def ghi" ехо $x |


tr [az] [AZ]
ABC DEF GHI

Ето още един начин за преобразуване на букви от малки в главни:

котка колони4.txt | tr '[:lower:]' '[:upper:]'

В допълнение към промяната на главните и малките букви, можете да използвате POSIX


класове знаци в командата tr :

• alnum: буквено-цифрови знаци


Machine Translated by Google

• алфа: азбучни знаци • cntrl:


контролни (непечатаеми) знаци • цифра:
цифрови знаци • графика:
графични знаци • малки:
малки азбучни знаци • print: печатаеми
знаци • punct: препинателни
знаци • интервал: празни знаци
• upper: главни букви знаци •
xdigit: шестнадесетични знаци
0-9 AF

Следният пример премахва белите интервали в променливата x (инициализирана


по-горе):

echo $x |tr -ds " " "" abcdefghi

Следната команда отпечатва всяка дума на отделен ред:

ехо "ab c" | tr -s " "\012"


а
b
°С

Следната команда замества всяка запетая с преместване на ред:

ехо "a,b,c" | tr -s "," "\n"


а
b
°С

Следващият пример замества новия ред във всеки ред с празно място,
което произвежда един ред изход:

'
cat test4.txt |tr '\n' '

Резултатът от предходната команда е тук:

abc def abc abc

Следващият пример премахва знака за нов ред в края на всеки ред текст в текстов
файл. Като илюстрация листинг 3.3 показва съдържанието на
abc2.txt.
Machine Translated by Google

ОБЯВКА 3.3: abc2.txt

Това е първи ред


Това е втори ред
Това е ред три
Четвърти ред
Пети ред
Шестият ред
Седмият ред

Следният кодов фрагмент премахва знака за нов ред в текстовия файл


abc2.txt:

tr -d '\n' < abc2.txt

Резултатът от предходния tr кодов фрагмент е тук:

Това е първи ред Това е втори ред Това е трети ред Четвърти ред Пети ред Шести ред Седми ред

Както можете да видите, в резултата липсва празно място между последователните редове,
които можем да вмъкнем с тази команда:

' < abc2.txt


tr -s '\n' '

Резултатът от модифицираната версия на tr кодовия фрагмент е тук:

Това е първи ред Това е втори ред Това е трети ред Четвърти ред Пети ред Шести ред Седми ред

Можете да замените знака за нов ред с точка „.“ с тази команда tr :

tr -s '\n' '.' < abc2.txt

Резултатът от предишната версия на tr кодовия фрагмент е тук:

Това е първи ред. Това е втори ред. Това е трети ред. Четвърти ред. Пети ред. Шести ред. Седми ред.

Командата tr с опцията -s работи на принципа едно към едно, което означава, че


последователността '.' има същия ефект като последователността '. '. Като вид визуализация
можем да добавим празно място след всяка точка '.' чрез комбиниране на командата tr с
командата sed (обсъдена в Глава 6), както е показано тук:

tr -s '\n' '.' < abc2.txt | sed 's/\./\. /g'


Machine Translated by Google

Резултатът от предходната команда е тук:

Това е първи ред. Това е втори ред. Това е ред три.


Четвърти ред. Пети ред. Шестият ред. Седмият ред.

Помислете за предходния фрагмент на sed по следния начин: „когато се срещне „точка“,


заменете я с „точка“, последвана от интервал, и направете това за всяко появяване на точка.“

Можете също така да комбинирате множество команди, като използвате символа „тръба“ на
bash. Например, следната команда сортира съдържанието на листинг 3.3, извлича „долните“ пет
реда текст, извлича редовете текст, които са уникални, и след това преобразува текста в главни
букви,

котка abc2.txt | сортиране | опашка -5 | уникален | tr [az] [AZ]

Ето резултата от предходната команда:

СЕДМИЯТ РЕД
ШЕСТИЯТ РЕД
ТОВА Е ПЪРВИ РЕД
ТОВА Е ТРЕТИ РЕД
ТОВА Е ВТОРИ РЕД

Можете също така да конвертирате първата буква на дума в главна (или в малка)
с командата tr , както е показано тук:

x="пица" x=`echo
${x:0:1} | tr '[az]' '[AZ]''${x:1}` echo $x

Малко по-дълъг (един допълнителен ред код) начин за преобразуване на първата буква в
главни букви са показани тук:

x="pizza"
first=`echo $x|cut -c1|tr [az] [AZ]` second=`echo $x|cut -c2-` echo
$first$second

Както можете да видите, възможно е да комбинирате множество команди, като използвате


символа bash pipe “|” за да произведете желания резултат.

ПРОСТ СЛУЧАЙ НА УПОТРЕБА


Machine Translated by Google

Примерният код в този раздел ви показва как да използвате командата tr , за да


замените контролния знак ^M с нов ред. Списък 3.4 показва съдържанието на набора от
данни controlm.csv , който съдържа вградени контролни знаци.

СПИСЪК 3.4 controlm.csv

IDN,ТЕСТ,WEEK_MINUS1,WEEK0,WEEK1,WEEK2,WEEK3,WEEK4,WEEK10,
WEEK12,WEEK14,WEEK15,WEEK17,WEEK18,WEEK19,WEEK21
^M1,BASO,,1.4,,0.8,,1.2,,1.1,,, 2.2,,,1.4^M1,BASOAB,,0-
.05,,0.04,,0.05,,0.04,,,0.07,,,0.05^M1,EOS,,6.1,,6.2,,7.5,, 6.6,,
,7.0,,,6.2^M1,EOSAB,,0.22,,0.30,,0.27,,0.25,,,0.22,,,0 .21^M1,HCT,,35.0,,34.2,,34.6,,34.3,,
,36.2,,,34.1^M1,HGB,,11 .8,,11.1,,11.6,,11.5,,,12.1,,,11.3^M1,LYM,,36.7

Листинг 3.5 показва съдържанието на файла controlm.sh , който илюстрира как да


премахнете контролните символи от controlm.csv.

СПИСЪК 3.5 controlm.sh

inputfile="controlm.csv"
removectrlmfile="removectrlmfile" tr -s '\r' '\n' < $inputfile >

$removectrlmfile

За удобство листинг 3.5 дефинира променливата inputfile за входния файл


и променливата removectrlmfile за изходния файл.
Резултатът от стартирането на shell скрипта в листинг 3.5 е тук:

IDN,ТЕСТ,WEEK_MINUS1,WEEK0,WEEK1,WEEK2,WEEK3,WEEK4,WEEK10,
WEEK12,WEEK14,WEEK15,WEEK17,WEEK18,WEEK19,WEEK21
1,BASO,,1.4,,0.8,,1.2,,1.1,,,2.2 ,,,1.4
1,BASOAB,,0.05,,0.04,,0.05,,0.04,,,0.07,,,0.05 1,EOS,,6.1,,6.2,,7.5,,6.6,,,7.0,,,6.2
1,EOSAB,,0,22,,0,30,,0,27,,0,25,,,0,22,,,0,21

Както можете да видите, задачата в този раздел се решава лесно чрез командата tr .
Обърнете внимание, че в предходния изход има празни полета, което означава, че е
необходима допълнителна обработка.
Можете също така да замените текущия разделител „,“ с различен разделител, напр
като „|“ символ, който се появява в следната команда:

cat removectrlmfile |tr -s ',' '|' > pipedfile

Полученият резултат е показан тук:

IDN|ТЕСТ|WEEK_MINUS1|WEEK0|WEEK1|WEEK2|WEEK3|WEEK4|WEEK10|
СЕДМИЦА12|СЕДМИЦА14|СЕДМИЦА15|СЕДМИЦА17|СЕДМИЦА18|СЕДМИЦА19|СЕДМИЦА21
Machine Translated by Google

1|BASO|1.4|0.8|1.2|1.1|2.2|1.4 1|BASOAB|0.05|0.04|
0.05|0.04|0.07|0.05 1|EOS|6.1|6.2|7.5|6.6|7.0|6.2 1|EOSAB|0.22 |
0,30|0,27|0,25|0,22|0,21

Ако имате текстов файл с множество разделители в произволен ред в множество файлове,
можете да замените тези разделители с един разделител чрез командата sed , която е разгледана в
глава 6.

КОМАНДАТА ЗА НАМИРАНЕ

Командата find поддържа много опции, включително една за отпечатване (показване) на


файловете, върнати от командата find , и друга за премахване на файловете, върнати от командата
find .
Освен това можете да посочите логически оператори като -a (И), както и -o (ИЛИ) в команда за
намиране . Можете също да посочите превключватели, за да намерите файловете (ако има такива),
които са били създадени, достъпни или модифицирани преди (или след) определена дата.
Няколко примера са тук:

намирам . -print показва всички файлове (включително поддиректории) -print |grep


намирам . "abc" показва всички файлове, чиито имена съдържат низа abc -print |grep "sh$" показва всички
файлове,
намирам . чиито имена имат суфикс
ш
намирам . -depth 2 -print показва всички файлове с дълбочина най-много 2 (включително поддиректории)

Можете също така да посочите времена за достъп, отнасящи се до файловете. Например atime, ctime и
mtime се отнасят съответно до времето за достъп, времето за създаване и времето за модификация на файл.

Като друг пример, следната команда намира всички файлове, променени за по-малко от 2 дни и отпечатва
броя на записите за всеки:

$ намери. -mtime -2 -exec wc -l {};

Можете да премахнете набор от файлове с командата find . Например, можете да премахнете


всички файлове в текущото дърво на директорията, които имат суфикс „m“, както следва:

намирам . -име "*m$" -print -exec rm {}


Machine Translated by Google

ЗАБЕЛЕЖКА Бъдете внимателни, когато премахвате файлове. Изпълнете предходната команда без exec
rm {} , за да прегледате списъка с файлове, преди да ги изтриете.

КОМАНДАТА TEE

Командата tee ви позволява да показвате изход на екрана и да пренасочвате изхода


към файл едновременно. Опцията -a ще добави последващ изход към посочения файл,
вместо да презапише файла. Ето един прост пример:

намирам . -print |grep "sh$" | тройник /tmp/син

Предходният кодов фрагмент пренасочва списъка с всички файлове в текущата директория (и тези
във всички поддиректории) към командата xargs , която след това търси и отпечатва всички редове, които
завършват с низа „sh“. Резултатът се показва на екрана и също се пренасочва към файла /tmp/blue.

намирам . -print |grep "^abc$" | tee -a /tmp/синьо

Предходният кодов фрагмент също пренасочва списъка с всички файлове в текущата


директория (и тези във всички поддиректории) към командата xargs , която след това търси
и отпечатва всички редове, които съдържат само низа „abc“. Резултатът се показва на
екрана и също се добавя към файла /tmp/blue.

КОМАНДИ ЗА КОМПРЕСИРАНЕ НА ФАЙЛОВЕ

Bash поддържа различни команди за компресиране на набори от файлове, включително командите


tar, cpio, gzip и gunzip . Следващите подраздели съдържат прости примери за това как да използвате тези
команди.

КОМАНДАТА НА ТАР

Командата tar ви позволява да компресирате набор от файлове в директория, за да


създадете нов tar файл, да декомпресирате съществуващ tar файл и също така да покажете
съдържанието на tar файл.
Опцията „c“ посочва „create“, опцията „f“ посочва „file“ и опцията „v“ посочва „verbose“.
Например следната команда създава компресиран файл, наречен testing.tar , и показва
файловете, които са включени в testing.tar по време на създаването на този файл:

tar cvf testing.tar *.txt


Machine Translated by Google

Компресираният файл testing.tar съдържа файловете със суфикс txt в текущата


директория и ще видите следния изход:

apple-care.txt checkin-
commands.txt iphonemeetup.txt outfile.txt

output.txt ssl-instructions.txt

Следната команда извлича файловете, които са в tar файла testing.tar:

tar xvf тестване.tar

Следващата команда показва съдържанието на tar файл без


декомпресиране на съдържанието му:

tar tvf тестване.tar

Предходната команда показва същия изход като командата ls -l , която показва дълъг
списък.
Опцията „z“ използва gzip компресия. Например следната команда създава
компресиран файл, наречен testing.tar.gz:

tar czvf testing.tar.gz *.txt

КОМАНДАТА CPIO

Командата cpio осигурява допълнително компресиране, след като създадете tar файл.
Например следната команда създава файла archive.cpio:

ls файл1 файл2 файл3 | cpio -ov > архив.cpio

Опцията „-o“ указва изходен файл, а опцията „-v“ указва „подробно“, което означава,
че файловете се показват, както са поставени в архивния файл. Опцията „-I“ указва „вход“,
а опцията „-d“ указва „дисплей“.

Можете да комбинирате други команди (като командата find ) с cpio


команда, пример за която е тук:

намирам . -име ".sh" | cpio -ov > shell-scripts.cpio


Machine Translated by Google

Можете да покажете съдържанието на файла archive.cpio със следната команда:

cpio -id < archive.cpio

Резултатът от предходната команда е тук:

файл1
файл2
файл3 1
блок

КОМАНДИТЕ GZIP И GUNZIP

Командата gzip създава компресиран файл. Например следното


командата създава компресирания файл filename.gz:

gzip име на файл

Извлечете съдържанието на компресирания файл filename.gz с командата gunzip :

gunzip име на файл.gz

Можете да създадете gzip tarballs (т.е. tar файл, използвайки gzip компресия), като
използвате следните
методи: Метод #1:

tar -czvvf archive.tar.gz [ВАШИЯТ СПИСЪК С ФАЙЛОВЕ]

Метод #2:

tar -cavvf archive.tar.gz [ВАШИЯТ-СПИСЪК С ФАЙЛОВЕ]

Опцията -a указва, че форматът за компресиране трябва да бъде автоматично


открит от разширението.

Командата bunzip2

Помощната програма bunzip2 използва техника за компресиране, подобна на gunzip2, с


изключение на това, че bunzip2 обикновено произвежда по-малки (по-компресирани) файлове от gzip.
Предлага се с всички Linux дистрибуции. За да компресирате с bzip2, използвайте следното:
Machine Translated by Google

bzip2 име на файл ls име


на
файл.bz2

Командата zip

Командата zip е друга помощна програма за създаване на zip файлове. Например, ако имате файловете,
наречени file1, file2 и file3, тогава следната команда създава файла file1.zip , който съдържа тези три файла:

zip файл?

Командата zip има полезни опции (като -x за изключване на файлове) и можете да


намерите повече информация в онлайн уроци.

КОМАНДИ ЗА ZIP И BZ ФАЙЛОВЕ

Има различни команди за работа с zip файлове, включително zdiff, zcmp,


zmore, zless, zcat, zipgrep, zipsplit, zipinfo, zgrep, zfgrep и зегреп.

Премахнете първоначалния „z“ или „zip“ от тези команди, за да получите


съответстваща „обикновена“ bash команда.
Например командата zcat е аналог на командата cat , така че можете да покажете
съдържанието на файл в .gz файл, без да извличате ръчно този файл и без да променяте
съдържанието на файла. Ето един пример: .gz

ls test.gz zcat
test.gz

Друг набор от помощни програми за bz файлове включва bzcat, bzcmp, bzdiff, bzegrep,
bzfgrep, bzgrep, bzless и bzmore.
Прочетете онлайн документацията, за да научите повече за тези команди.

СЕПАРАТОР ЗА ВЪТРЕШНО ПОЛЕ (IFS)

Вътрешният разделител на полето е важна концепция в скриптовете на обвивката,


която е полезна при манипулиране на текстови данни. Вътрешен разделител на полето (IFS)
е променлива на средата, която съхранява разделящи знаци. IFS е разделителният низ по
подразбиране , използван от работеща обвивка.
Помислете за случая, в който трябва да итерираме думи в низ или стойности, разделени
със запетая (CSV). Посочете IFS="," за показване на всеки подниз на a
Machine Translated by Google

отделен ред. Да предположим например, че shell скрипт съдържа следните редове:

данни="възраст,пол,улица,щат"
IFS=$',' за
елемент в $data do echo

Елемент: $item готов

Резултатът от предходния кодов блок е тук:

Артикул: възраст
Артикул: пол
Артикул: ул
Артикул: състояние

Имайте предвид, че можете също да използвате командата awk (обсъдена в глава 7), за
да произведете същия изход.
Следващият раздел съдържа примерен код, който разчита на стойността на IFS до
извличане на данни правилно от набор от данни.

ДАННИ ОТ ДИАПАЗОН ОТ КОЛОНИ В НАБОР ДАННИ

Листинг 3.6 показва съдържанието на набора от данни datacolumns1.txt. Списък 3.7


показва съдържанието на шел скрипта datacolumns1.sh , който илюстрира как да извлечете
данни от набор от колони от набора от данни в листинг 3.6.
Между другото, този примерен код съдържа цикъл while , който е един от няколкото вида
цикли, които са налични в bash. Като такъв, този примерен код включва „препращане
напред:“ с помощта на bash конструкция, преди да бъде обсъден подробно.
Въпреки това, вие или вече сте запознати с концепцията за цикъл while , или имате
интуитивна представа за целта му, така че ще можете да разберете кода в този примерен код.

СПИСЪК 3.6 datacolumns1.txt

#23456789012345678901234567890
1000 Джейн Едуардс
2000 Том Смит
3000 Дейв Дел Рей

ЛИСТИНГ 3.7 datacolumns1.sh

# емпид: 03-09
Machine Translated by Google

# fname: 11-20 # lname:


21-30 IFS=''

inputfile="datacolumns1.txt"

while read line do pound="`echo

$line |grep '^#'`"

if [ x"$pound" == x"" ] then echo "line: $line"

empid=`echo "$line" |cut -c3-9` echo


"empid: $empid"

fname=`echo "$line" |cut -c11-19` echo "fname: $fname"

lname=`echo "$line" |cut -c21-29` echo "lname: $lname"

ехо "--------------"
fi

done < $inputfile

Списък 3.7 задава стойността на IFS на празен низ, който е необходим, за да работи
коректно този скрипт на обвивката (опитайте да стартирате този скрипт без настройка
на IFS и вижте какво ще се случи). Тялото на този скрипт съдържа цикъл while , който
чете всеки ред от входния файл, наречен datacolumns1.txt , и задава променливата на
паунда равна на „v“, ако редът не започва със знака „#“ ИЛИ задава променливата на
паунда равна на целият ред, ако започва със знака „#“. Това е проста техника за
филтриране на линии въз основа на първоначалния им характер.
Операторът if се изпълнява за редове, които не започват със знак „#“, а променливите empid, fname и lname се инициализират

съответно със знаците в колони от 3 до 9, след това от 11 до 19 и след това от 21 до 29. Стойностите на тези три променливи се отпечатват

всеки път, когато се инициализират. Както можете да видите, тези променливи се инициализират чрез комбинация от командата echo и

командата cut и стойността на IFS е необходима, за да се гарантира, че командата echo не премахва празни интервали.

Резултатът от листинг 3.7 е показан тук:

ред: 1000 Джейн Едуардс

empid: 1000 fname:


Джейн
Име: Едуардс
--------------

линия: 2000 empid: Том Смит

2000 fname: Том


Machine Translated by Google

Име: Смит
--------------
линия: 3000 empid: Дейв Дел Рей
3000 fname: Dave
lname: Del Ray

--------------

РАБОТА С НЕРАВНИ РЕДОВЕ В НАБОРИ ДАННИ

Листинг 3.8 показва съдържанието на набора от данни uneven.txt , който съдържа


редове с различен брой колони. Листинг 3.9 показва съдържанието на bash скрипта
uneven.sh , който илюстрира как да генерирате набор от данни, чиито редове имат еднакъв
брой колони.

ОБЯВКА 3.8: uneven.txt

abc1 abc2 abc3 abc4 abc5 abc6


abc1 abc2
abc3 abc4 abc5 abc6

ОБЯВКА 3.9: uneven.sh

inputfile="uneven.txt"
outputfile="even2.txt"

# ==> четири полета на ред #метод #1:


четири полета на ред cat $inputfile | xargs -n 4
>$outputfile #метод #2: два равни реда #xargs -L 2 <$inputfile >
$outputfile

echo "входен файл:" cat


$inputfile

echo "изходен файл:" cat


$outputfile

Листинг 3.9 съдържа две техники за повторно подравняване на текста във входния
файл, така че изходът да се появява с четири колони във всеки ред. Както можете да видите,
и двете техники включват командата
xargs (което е интересно използване на командата). xargs

Стартирайте кода в листинг 3.9 и ще видите следния резултат:

abc1 abc2 abc3 abc4


Machine Translated by Google

abc5 abc6 abc1 abc2 abc3


abc4 abc5 abc6

РЕЗЮМЕ

Тази глава ви показа примери за това как да използвате някои полезни и многофункционални bash
команди. Първо научихте за bash командите join, fold, split, sort и uniq. След това научихте за командата find
и командата. Освен това научихте за различни начини за използване на командата tr , която също xargs

е в случая на употреба в тази глава.

След това видяхте някои команди, свързани с компресията, като cpio и tar, които ви
помагат да създавате нови компресирани файлове и също така ви помагат да изследвате
съдържанието на компресираните файлове.
Освен това научихте как да извличате диапазони от колони от данни, както и
полезността на опцията IFS .
Machine Translated by Google

ГЛАВА 4

УСЛОВНА ЛОГИКА И ЦИКЛИ

T
неговата глава ви запознава с операторите (за числови данни и низ
променливи), условна логика (if/else/fi) и няколко вида цикли (for, while и until) в
bash.
Първата част на тази глава ви показва как да извършвате аритметични
операции и операторите, които са налични за това. Ще видите също как да
присвоявате стойности на променливи и след това как да четете въведеното от
потребителя в скрипт на обвивка.
Втората част от тази глава ви показва как да използвате командата test за
променливи, файлове и директории (като например определяне дали две
променливи са равни). Ще научите как да използвате различни релационни, булеви
и низови оператори.
Третият раздел въвежда условна логика (if/else/fi), операторът за превключване
case/esac , заедно с цикли for , вложени цикли for , цикли while и цикли until . Ще
научите също как да дефинирате свои собствени персонализирани функции в шел
скриптове.
Последният раздел ви показва как да работите с масиви в bash, което включва
примери за повторение на елементи от масив и актуализиране на техните
съдържание.

БЪРЗ ПРЕГЛЕД НА ОПЕРАТОРИТЕ В BASH

Bash shell поддържа следните оператори, всеки от които е разгледан по-


подробно в тази глава:
Machine Translated by Google

• Аритметични оператори •
Стрингови оператори
• Файлови тестови
оператори • Булеви оператори

The израз командата често се използва за извършване на аритметични операции (добавяне,


изваждане, умножение или деление) върху числови стойности.
Аритметичните оператори ви позволяват да сравнявате двойки числа и двойки низове.
Операторите за сравняване на числа включват -eq, -lt и -gt за сравняване на равенство,
съответно по-малко от и по-голямо от. Операторите за низове за сравняване на низове
включват ==, < и > съответно за сравняване на равенство, по-малко от и по-голямо от.

Някои оператори, свързани с файлове, които са налични в bash, включват -f, -d, -e за проверка
дали името на файл е съответно файл, директория или проверка за съществуването на файл.

Булевите оператори (наричани още логически оператори) в bash са -a, -o и


! съответно за операция И, ИЛИ и отрицание.

АРИТМЕТИЧНИ ДЕЙСТВИЯ И ОПЕРАТОРИ

Аритметичните оператори включват +, -, * и /, съответно за събиране, изваждане, деление


и умножение на две числа. Операторът % е операторът за модул, който връща остатъка от
деленето на две числа. Използвайте оператора = , за да присвоите стойност на операнд, == , за

да проверите дали два операнда са равни, и !=, за да проверите дали два операнда са неравни.

Аритметиката в обвивките на POSIX се извършва с $ и двойни скоби, както е показано тук:

ехо "$(($num1+$num2))"

Освен това можете да използвате заместване на команда, за да присвоите резултата от an


аритметична операция към променлива:

num1=3
num2=5
x=`echo "$(($num1+$num2))"`

По-проста алтернатива на предходния кодов фрагмент включва командата, която израз


се обсъжда в следващия раздел.
Machine Translated by Google

Командата expr

Предишният раздел ви показва как да съберете две числа с помощта на двойни


скоби; друга техника използва командата expr , както е показано тук:

израз $num1 + $num2

Както вероятно очаквате, командата поддържа


израз аритметични операции,
включващи твърдо кодирани числа, както е показано в следния пример, който добавя
две числа:

sum=`expr 2 + 2` echo "Сумата:


$sum"

Това ще доведе до следния резултат:

Сумата: 4

Необходими са интервали между операторите и изразите (така че 2+2 е


неправилно), а изразите трябва да са вътре в знаци за обратна отметка (наричани
още обърнати запетаи).
Интересно използване на израз командата е за намиране на дължината на a
низа, както е показано тук:

x="abc" expr

"$x" : '.*' 3 echo ${#x} 3 echo

'expr "$x" : '.*'' 3

Аритметични оператори

Bash shell поддържа аритметичните операции събиране, изваждане, умножение


и деление съответно чрез операторите +, -, * и /. Следният пример илюстрира тези
операции.

х=15

y=4

sum=`expr $x + $y`
Machine Translated by Google

diff=`expr $x - $y` prod=`expr


$x \* $y` div=`expr $x / $y`
mod=`expr $x % $y`

echo "sum = $sum" echo


"difference = $diff" = $prod" echo "product echo
$div" = $mod" echo "quotient =
"modulus

Ето няколко примера (да приемем, че операторите г имат числени стойности) на


x и равенство („==“) и неравенство („!="):

[ $x == $y ] връща false [ $x != $y ]
връща true

Обърнете внимание на необходимите интервали в предходните изрази. Всички аритметични


изчисления се извършват с помощта на дълги цели числа.

Булеви и числови оператори

Bash поддържа релационни оператори, които са специфични за числови стойности:


те няма да работят правилно за низови стойности, освен ако стойността им не е числова.
Ето списък на някои често срещани оператори:

• $a -eq $b проверява дали $a и $b са равни. •


$a -ne $b проверява дали $a и $b не са равни. •
$a -gt $b проверява дали $a е по-голямо от $b.
• $a -lt $b проверява дали $a е по-малко от $b. •
$a -ge $b проверява дали $a е по-голямо или равно
на $b. • $a -ge $b проверява дали $a е по-малко или равно на $b.

Имайте предвид, че предходните изрази са записани в двойка квадратни скоби с


интервали от двете страни: [ $a -eq $b ], [ $a -ne $b ] и т.н.

Съставни оператори и числови оператори

Да предположим,че a е равно на 5 и променлива b е равно на 15 в следните примери:


Machine Translated by Google

[ ! false ] е вярно.

-о Ако един операнд е верен, тогава условието е вярно: [ $a -lt 20 -o $b


-gt 100 ] е вярно.
-а Ако и двата операнда са верни, тогава условието е вярно (в противен случай е невярно):

[ $a -lt 20 -a $b -gt 100 ] е невярно.

! Операторът not обръща стойността на условието.

\( … \) Групирайте изрази, като ги оградите в \( и \).

Логическите условия и другите тестове обикновено се поставят в квадратни скоби []. Имайте предвид,

че има интервал между квадратните скоби и операндите. Ще покаже грешка, ако не е предоставено място.

Пример за валиден синтаксис е както следва:

[$var -eq 0]

Изпълнението на аритметични условия върху променливи или стойности може да се извърши по


следния начин:

• [ $var -eq 0 ] # вярно, когато $var е равно на 0. • [ $var -ne 0 ] # вярно,


когато $var е различно от 0.

Можете също да комбинирате предходните оператори с -a (И) или -o (ИЛИ)

за уточняване на условията за изпитване на съединението, както е показано тук:

[ $var1 -ne 0 -a $var2 -gt 2 ] [ $var1 -ne 0 -o $var2


-gt 2 ]

Командата test извършва проверки на условия и намалява броя на скобите. Същият набор от тестови
условия, затворени в [] , може да се използва за тестовата команда, както е показано тук:

if [ $var -eq 0 ]; след това ехо "Вярно"; фи

може да се напише като

ако тест $var -eq 0; след това ехо "Вярно"; фи


Machine Translated by Google

РАБОТА С ПРОМЕНЛИВИ

Вече видяхте някои примери за променливи в bash и този раздел предоставя


информация за това как да присвоите стойности на променливи. Ще видите също как да
използвате условна логика за тестване на стойностите на променливите.
Винаги помнете, че bash променливите нямат информация, свързана с типа, което
означава, че не се прави разлика между число и низ (подобно на JavaScript). Въпреки това
ще получите съобщение за грешка, ако се опитате да извършите аритметични операции
върху нечислови стойности в bash (което не винаги е така в JavaScript).

Присвояване на стойности на променливи

Този раздел съдържа някои прости примери за присвояване на стойности на


променливи с двойни и единични кавички:

x="abc"

y="123" echo
"x = $x и y = ${y}" echo "xy = $x$y" echo "двойни и
единични кавички: $x" '$x'

Предходният кодов блок води до следния изход:

x = abc и y = 123 xy = abc123


двойни и
единични кавички: abc $x

Уверете се, че не вмъквате празно пространство между променлива и нейната стойност.


Например, ако въведете следната команда:

z = "abc"

Ще видите следния изход:

-bash: z: командата не е намерена

Можете обаче да вмъкнете интервал между текстовите низове и променливите в


командата echo , както видяхте в предишния кодов блок.
Още нещо, което трябва да имате предвид: следният синтаксис е невалиден, защото е
променливата предшестван от символа $ :
г
Machine Translated by Google

$y=3
-bash: =3: командата не е открита

Листинг 4.1 показва съдържанието на variable-operations.sh that


илюстрира как да присвоите променливи с различни стойности и да ги актуализирате.

ЛИСТИНГ 4.1: variable-operations.sh

#length of myvar:
myvar=123456789101112 echo ${#myvar}

#print последните 5 знака от myvar: echo ${myvar: -5}

#10 ако myvar не е присвоен echo ${myvar:-10}

#последните 10 символа на myvar ехо ${myvar:


-10}

#заместете част от низ с ехо: ехо ${myvar//123/999}

#събиране на цели числа a към b и присвояване на c: a=5

b=7
c=$((a+b)) echo "a:
$ab: $bc: $c"

# други начини за изчисляване на c: c=`expr $a +


$b` echo "c: $c" c=`echo "$a+
$b"|bc` echo "c: $c"

Стартирайте кода в листинг 4.1 и ще видите следния резултат:

15
01112
123456789101112
6789101112
999456789101112 a: 5 b: 7 c:
12

Командата за четене за потребителско въвеждане


Machine Translated by Google

Следният оператор е синтаксисът за четене на знаци от входа в променливата


myvar:

прочетете -n брой_символи myvar

Например следният кодов фрагмент чете два знака от командния ред (под формата
на въвеждане от потребителя) и след това показва тези два знака:

$ read -n 2 var echo


"var: $var"

С командата read са възможни различни други опции . Например,


следната команда чете парола в режим без ехо :

четене -s вар

Предходният кодов фрагмент ви позволява да въвеждате текст, докато натиснете


<RETURN>, нито един от които няма да се покаже (което е полезно за въвеждане на
парола).
От друга страна, следният кодов фрагмент показва знаците, които въвеждате от
командния ред, и присвоява тези знаци на променливата var, след като натиснете
<RETURN>:

read -p "Въведете вход:" var

БУЛЕВИ ОПЕРАТОРИ И ОПЕРАТОРИ С НИЗОВЕ

Има различни оператори в bash за тестване на низови променливи и комбиниране на тези оператори с булеви оператори. Да

предположим, че променливите x и y

имат съответно стойностите „abc“ и „efg“ :

[ $x = $y ] [$x != е
$y ] [ -z $x ]

невярно. истина е. е невярно, защото $a


[ -n $x ] има ненулева дължина. е вярно, защото
[$x] $a има ненулева дължина. е невярно, защото $x е непразен низ.
Machine Translated by Google

Можете също така да комбинирате предходните оператори, за да образувате съставен


изрази, подобни на съставните изрази в предишния раздел.
Имайте предвид, че операторът „==“ е за сравнения на низове, докато „-eq“ е за
числени тестове и числени сравнения. Можете също да определите дали даден низ има
ненулева дължина, както е показано тук:


-n s1 Низът s1 има ненулева дължина. -z s1

Низът s1 има нулева дължина.

Когато извършвате сравнение на низове, използвайте двойни квадратни скоби,


защото единичните скоби понякога могат да доведат до грешки.
Два низа могат да бъдат сравнени, за да се определи дали са еднакви, както следва:

[[ $str1 = $str2 ]]: вярно, когато str1 е равно на str2 [[ $str1


== $str2 ]]: алтернативен метод за проверка за равенство на низове

Можем да проверим дали два низа не са еднакви, както следва:

[[ $str1 != $str2 ]]: вярно, когато str1 и str2 не съвпадат

Можем да открием по-малкия или по-големия низ по азбучен ред, както следва:

[[ $str1 > $str2 ]]: true, когато str1 е по-голям от по азбучен ред
str2

[[ $str1 < $str2 ]]: вярно, когато str1 е по-малък по азбучен ред от str2
[[ -z $str1 ]]: вярно, ако str1 съдържа празен низ,
[[ -n $str1 ]]: вярно, ако str1 съдържа непразен низ

Съставни оператори и низови оператори

Комбинирайте множество условия, свързани с низове, като използвате логическите оператори


&& и || както следва:

if [[ -n $str1 ]] && [[ -z $str2 ]] ; след това команди;

фи
Machine Translated by Google

Разгледайте следния пример:

"
str1="Не е празен str2="" ако
[[ -n $str1 ]]
&& [[ -z $str2 ]]; тогава echo str1 не е празен и str2 е празен низ.

фи

Резултатът е както следва:

str1 не е празен, а str2 е празен низ.

Понякога ще видите bash скриптове (като свързани с инсталацията shell скриптове),


които съдържат съставни изрази за извършване на множество операции. По-специално
операторът && се използва за „свързване“ на множество команди, които се изпълняват
последователно (по начин отляво надясно). Всяка команда в последователността се
изпълнява само ако всички предходни команди в последователността са изпълнени
успешно. Ако текущата команда (в последователност) не се изпълни успешно, останалите
команди (ако има такива), които се появяват от дясната страна на неуспешната команда,
няма да бъдат изпълнени.
Например, следният кодов блок използва оператора && за първо създаване
директория, след това cd в тази директория и след това изведете съобщение:

OLDDIR=`pwd` cd /
tmp
CURRDIR=`pwd` echo
"текуща директория: $CURRDIR" mydir="/tmp/abc/def" mkdir -p $mydir && cd $mydir &&
echo "сега в $mydir" newdir=`pwd` echo "нова директория: $newdir" echo "нова директория:
`pwd`" cd $OLDDIR
echo "текуща директория: `pwd`"

На този етап сте запознати с всички bash команди в предходния кодов блок. Опитайте
се да предвидите изхода, преди да стартирате предходния кодов блок. (Бяхте ли прав?)

ФАЙЛОВИ ТЕСТ ОПЕРАТОРИ


Machine Translated by Google

Bash shell поддържа множество оператори за тестване на различни свойства


файлове. Да предположим, че променливият файл е непразен текстов файл, който е прочел,
разрешения за писане и изпълнение:

• -b файл проверява дали файлът е блоков специален файл.



-c файла проверява дали файлът е файл със специални знаци.
• -d файл проверява дали файлът е директория.
• -e файл проверява дали файлът съществува.

• -f файл проверява дали файлът е обикновен файл.



-g файла проверява дали файлът има зададен бит за групов идентификатор (SGID).

• -k файл проверява дали файлът има зададен свой „залепващ бит“.



-p файла проверява дали файлът е наименуван канал.
• -t файл проверява дали файловият дескриптор е отворен и свързан с a
терминал.

-u файла проверява дали файлът има зададен бит за потребителски идентификатор (SUID).
• -r файла проверява дали файлът е четим.
• -w файл проверява дали файлът може да се записва.
• -x файл проверява дали файлът е изпълним.

-s файла проверява дали файлът е с размер по-голям от 0.
• -e файл проверява дали файлът съществува.

• f1 -nt f2 Файл f1 е по-нов от файл f2.


• f1 -ot f2 Файл f1 е по-стар от файл f2.

Пример за тестване за съществуването на файл с опцията -e е


показано тук:

fpath="/etc/passwd"
if [ -e $fpath ]; тогава
echo Файлът съществува;
друго
ехо Не съществува;
фи

Сложни оператори и файлови оператори

Комбинирайте булеви оператори и оператори, свързани с файлове, с &&


(„И“) оператор или || („ИЛИ“) оператори. Следният пример
проверява дали файлът съществува и дали има писмени разрешения:
Machine Translated by Google

fpath="/tmp/somedata" if [ -e $fpath ] &&


[ -w $fpath ] then echo "Файл $fpath съществува и може да се

записва" else

if [ then ! -e $fpath ]
echo

"Файлът $fpath не съществува" else echo "Файлът $fpath

съществува, но не може да се записва" fi

фи

Забележете използването на оператора && в първия оператор if в предходния


кодов блок. Следният синтаксис е неправилен, защото има два последователни
оператора и bash shell няма да интерпретира правилно синтаксиса:

if [ -e $fpath -a -w $fpath ]

Забележете, че съставните оператори с низови оператори също използват &&


или || оператори:

if [[ -n $str1 ]] && [[ -z $str2 ]] ;

Съставните оператори с числови оператори обаче не изискват


&& или || оператори, както е показано тук:

[ $a -lt 20 -a $b -gt 100 ]

УСЛОВНА ЛОГИКА С ИЗПЪЛНЕНИЯ IF/ELSE/FI

Bash поддържа условна логика, но с малко по-различен синтаксис от другите


езици за програмиране. Следващият пример ви показва как да използвате израз if/
else/if в bash, който отпечатва едно съобщение, ако променливата x (която е
инициализирана със стойност 25) е по-малка от 30 и друго съобщение, ако стойността
на x не е по-малка от 30:

x=25 if
[ $x -lt 30 ] then echo "x е по-
малко
от 30"
Machine Translated by Google

друго
echo "x е поне 30"
фи

Листинг 4.2 показва съдържанието на скрипта на обвивката testvars.sh, който


проверява дали променливата x е дефинирана.

ОБЯВКА 4.2: testvars.sh

x="abc"

if [ -n "$x" ] then echo "x е

дефиниран: $x" else

echo "x не е дефиниран" fi

Листинг 4.2 инициализира променливата x със стойността abc и след това използва конструкцията if/

else/fi , за да определи дали x е инициализирана и да отпечата подходящо съобщение. Стартирайте shell

скрипта в листинг 4.2 и ще видите следния резултат:

X е дефинирано: abc

Листинг 4.3 показва съдържанието на шел скрипта testvars2.sh , който проверява дали променливата
е недефиниран.
г

ОБЯВКА 4.3: testvars2.sh

if [ -z "$y" ] тогава

y="def" echo
"y е дефинирано: $y" else echo "y е

дефинирано: $y" fi

Листинг 4.3 първо проверява дали променливата y е дефинирана и тъй като тя не е дефинирана,

следните два оператора се изпълняват за инициализиране и след това отпечатване на съобщение:


г

y="def" echo
"y е дефинирано: $y"
Machine Translated by Google

Стартирайте shell скрипта в листинг 4.3 и ще видите следния резултат:

y е дефинирано: def

СЛУЧАЙЪТ/ИЗЯВЛЕНИЕ НА ESAC

Операторът case/esac е аналогът на оператора switch в други езици за


програмиране. Този оператор ви позволява да тествате различни условия, които могат
да включват метасимволи. Често срещан сценарий включва тестване на въведеното
от потребителя: можете да проверите дали потребителите са въвели низ, който
започва с главна или малка буква „n“ (за не), както и „y“ (за да).
Листинг 4.4 показва съдържанието на case1.sh , който проверява различни
условия в изявление за случай/esac .

ОБЯВКА 4.4: case1.sh

x="abc"

case $x in a)
echo "x е a" ;; c) ехо "x е c" ;; a*)
echo "x започва с a" ;; *) echo
"няма съвпадения" ;;

esac

Листинг 4.4 започва с инициализиране на променливата x със стойността abc,


последвана от ключовата дума case , която проверява различни условия. Както можете
да видите, x отговаря на третото условие, което е вярно, защото стойността на x
започва с буквата a. Стартирайте shell скрипта в листинг 4.4 и ще видите следния
резултат:

x започва с a

Листинг 4.5 ви показва как да подканите потребителите за входен низ и след това
да обработите този вход чрез оператор case/esac .

ОБЯВКА 4.5: UserInfo.sh

"
echo -n "Моля, въведете първото си име: прочетете fname
Machine Translated by Google

"
echo -n "Моля, въведете вашето фамилно име: прочетете lname

echo -n "Моля, въведете вашия град: " прочетете


град

fullname="$fname $lname" echo


"$fullname живее в $city"

случай $city в
San*) echo "$fullname живее в Калифорния " ;;
Чикаго) echo "$fullname живее във Ветровития град " *) echo "$fname живее в ;;
ла-ла земя " ;;
esac

Списък 4.5 започва с подкана към потребителите за тяхното име, фамилия и град
и след това присвояване на тези стойности съответно на променливите fname, lname
и city . След това променливата fullname се дефинира като конкатенация на стойностите
на fname и lname.
Следващата част от листинг 4.5 е ключовата дума case , която проверява дали
променливата city започва с низа San или дали променливата city е равна на Chicago.
Третата опция е опцията по подразбиране, която е вярна, ако и двете предходни
условия са неверни.
Списък 4.6 показва съдържанието на StartChar.sh , който проверява типа на първия
знак на низ, предоставен от потребителя.

ЛИСТИНГ 4.6: StartChar.sh

докато (true) do echo


-n

"Въведете низ: " прочетете промен

case ${var:0:1} in [0-9]*) echo


"$var започва с цифра" ;;
[AZ]*) echo "$var започва с главна буква" ;; [az]*) echo "$var започва с малка буква" ;;
*) echo "$var започва с друг символ" ;;

esac
Свършен

Списък 4.6 започва с подкана към потребителите за низ и след това инициализира
променлива var с този входен низ.
Следващата част от листинг 4.6 е ключовата дума case , която проверява дали
променливата var започва с 0 или повече цифри, главни букви или малки букви
Machine Translated by Google

букви и след това показва подходящо съобщение. Условието по подразбиране се


изпълнява, ако нито едно от предходните условия не е вярно.
Листинг 4.7 показва съдържанието на StartChar2.sh , което проверява типа на
първата двойка знаци на низ, предоставен от потребителя.

ЛИСТИНГ 4.7: StartChar2.sh

докато (вярно) правя

echo -n "Въведете низ: " прочетете вар

case ${var:0:2} in [0-9][0-9]) echo


"$var започва с to digit" ;;
[AZ][AZ]) echo "$var започва с две главни букви" ;; [az][az]) echo "$var започва с две малки букви" ;;

*) echo "$var започва с друг модел" ;;


esac
Свършен

Списък 4.7 започва с цикъл while , чието съдържание е идентично със съдържанието
на листинг 4.6 (можете да прочетете предходния раздел за обяснение на кода).
Единствената разлика е, че този примерен код се повтаря безкрайно и можете да
натиснете ctrl-c , за да прекратите изпълнението на скрипта на обвивката.
Списък 4.8 показва съдържанието на StartChar3.sh , който проверява типа на първия
знак на низ, предоставен от потребителя.

ЛИСТИНГ 4.8: StartChar3.sh

докато (вярно) правя

echo -n "Въведете низ: " прочетете вар

случай ${var:0:1} в
[0-9]*) echo "$var започва с цифра" ;; [[:upper:]]) echo "$var започва с главна
буква" ;; [[:lower:]]) echo "$var започва с малка буква" ;; echo "$var започва с друг символ" ;; *)

esac
Свършен

Списък 4.8 също започва с цикъл while , който съдържа оператор case/esac . В този
пример обаче условията включват нула или повече
Machine Translated by Google

цифри, главни букви и малки букви. В допълнение, този примерен код също се
повтаря безкрайно и можете да натиснете ctrl-c, за да прекратите изпълнението на
скрипта на обвивката.

РАБОТА С НИЗОВЕ В SHELL СКРИПТОВЕ

Обърнете внимание на синтаксиса на „къдрави скоби“ във втория кодов фрагмент.


Листинг 4.9 показва съдържанието на substrings.sh , което илюстрира примери за
синтаксиса на „къдрави скоби“ за намиране на поднизове на даден низ.

ЛИСТИНГ 4.9: substrings.sh

x="abcdefghij" echo $
{x:0} echo ${x:1}
echo ${x:5} echo
${x:7:3}

ехо ${x:-4} ехо ${x:


(-4)} ехо ${x: -4}

Резултатът от предходните echo изрази е тук:

abcdefghij
bcdefghij fghij
hij

abcdefghij ghij
ghij

Списък 4.9 инициализира променливата x като abcdefghij, последвана от три


ехо израза, които показват поднизове на променливата x, започващи от индекс 0,
1 и 5. Четвъртият ехо израз показва подниза на x , който започва от колона 7 и има
дължина 3 .
Следващата част от листинг 4.9 съдържа три оператора за ехо , които определят
отрицателни стойности за позиции на колони, което означава, че позицията на
индекса се изчислява по начин отдясно наляво. Например изразът ${x: -4} се
отнася до най-десните 4 знака в променливата x, която е равна на ghij.
Обаче изразът ${x:-4} е цялата стойност на низа на x , защото там
Machine Translated by Google

е липсващ интервал. И накрая, изразът ${x:(-4)} се интерпретира, както очакваме,


което ще рече, че той също е равен на ghij.
Следващата част от тази глава обсъжда конструкции като изрази for, while и until ,
които можете да използвате в шел скриптове.

РАБОТА С ЦИКЛИ

Bash shell поддържа различни конструкции, които ви позволяват да обикаляте


през набор от стойности, като масив и списък с имена на файлове. Няколко конструкции
на цикъл са налични в bash, включително конструкция на цикъл for , цикъл while и
цикъл unless . Следващите подраздели илюстрират как можете да използвате всяка от
тези конструкции.

Използване на for Loop

Bash shell поддържа for цикъла, чийто синтаксис е малко по-различен


от други езици (като JavaScript и Java).
Следният кодов блок ви показва как да използвате for цикъл за итерация през
набор от файлове в текущата директория.

за f в `ls *txt`
do
echo "file: $f" done

Резултатът от предходния for цикъл зависи от файловете със суфикс txt , които са
в директорията, където стартирате for цикъла (ако няма такива файлове, тогава for
цикълът не прави нищо).
Листинг 4.10 показва съдържанието на renamefiles.sh2 , което илюстрира как
за преименуване на набор от файлове в директория.

ЛИСТИНГ 4.10: renamefiles.sh2

newsuffix="txt"

за f в `ls *sh`
do
base='echo $f |cut -d"." -f1' суфикс='echo $f |cut -d"." -f2'

newfile="${base}.${newsuffix}"
Machine Translated by Google

echo "файл: $f нов: $нов файл"

#или 'cp', или 'mv' файла #mv $f $newfile #cp $f $newfile


done

Листинг 4.10 инициализира променливата newsuffix със стойността txt, последвана


от for цикъл, който обикаля файловете, чийто суфикс е sh. Променливата f е
променливата на цикъла, която е присвоена на всяко от тези имена на файлове.
Първата част от цикъла for присвоява променливите base и suffix съответно с
началната част и оставащата част от всяко име на файл, използвайки точка (“.”) като
разделител.
След това променливата newfile е конкатенацията на стойността на променливата
base със стойността на променливата newsuffix, с точка (“.”) като разделител.

Следващата част от листинг 4.10 е ехо оператор, който показва стойността на


променливата newfile. Можете да декоментирате всяка от последните две команди, в
зависимост от това дали искате да направите копия на съществуващите файлове или
искате да преименувате файловете.

ПРОВЕРКА НА ФАЙЛОВЕ В ДИРЕКТОРИЯ

Примерният код в този раздел съдържа for цикъл, който проверява за различни
свойства на файловете в текущата директория.
Листинг 4.11 показва съдържанието на checkdir.sh , което отчита броя на
директориите, изпълними файлове, четими файлове и ASCII файлове в текущата
директория.

ОБЯВКА 4.11: checkdir.sh

#!/bin/bash #
инициализиране на променливи „брояч“ TOTAL_FILES=0

ASCII_FILES=0
NONASCII_FILES=0
READABLE_FILES=0 EXEC_FILES=0

ДИРЕКТОРИИ=0

за f в „ls“.
направи
Machine Translated by Google

TOTAL_FILES=`израз $TOTAL_FILES + 1`

ако [ -d $f ] тогава

ДИРЕКТОРИ=`expr $ДИРЕКТОРИИ + 1` fi

ако [ -x $f ] тогава

EXEC_FILES=`израз $EXEC_FILES + 1`
фи

ако [ -r $f ] тогава

READABLE_FILES=`израз $READABLE_FILES + 1`
фи

readable=`file $f` ascii=`echo


$readable |grep ASCII` if [ "$ascii" != "" ] then

ASCII_FILES=`израз $ASCII_FILES + 1`
else
#echo "четливо: $четливо"
NONASCII_FILES=`expr $NONASCII_FILES + 1` fi

Свършен

# резултати: echo

"TOTAL_FILES: echo "ДИРЕКТОРИИ: $TOTAL_FILES"


$DIRECTORIES"
"EXEC_FILES: echo "ASCII_FILES: $EXEC_FILES" echo
$ASCII_FILES" echo "НЕ-
ASCII_FILES: $NONASCII_FILES"

Листинг 4.11 инициализира някои свързани с броя променливи, последвани от


for цикъл, който обикаля файловете в текущата директория. Тялото на цикъла for
съдържа множество блокове с условен код, които определят дали текущият файл е
директория, изпълним ли е, четим ли е и дали текущият файл е ASCII файл.

Последната част от листинг 4.11 показва стойностите на променливите, свързани


с броя. Стартирайте кода в листинг 4.11 и ще видите нещо като следния изход
(резултатите, показани тук, са за една от моите поддиректории):

TOTAL_FILES: 33
ДИРЕКТОРИИ: 1
Machine Translated by Google

EXEC_FILES: 26
ASCII_FILES: 29
НЕ-ASCII_ФАЙЛОВЕ: 4

РАБОТА С ВЛОЖЕНИ ЦИКЛИ

Този раздел е главно за забавление: ще видите вложен цикъл за показване на


„триъгълен“ изход. Този примерен код използва масив с двойка стойности: масивите
в bash се обсъждат в последния раздел на тази глава. Списък 4.12 показва
съдържанието на nestedloops.sh , което илюстрира как да се покаже редуващ се набор
от символи в триъгълна форма.

ЛИСТИНГ 4.12: nestedloops.sh

#!/bin/bash

outermax=10
символа[0]="#"
символа[1]="@"

за (( i=1; i<${outermax}; i++ )); направете за (( j=1; j<${i}; j++ )); do

printf "%-2s" ${symbols[($i+$j)%2]} done printf "\n" done

за (( i=1; i<${outermax}; i++ )); направете за (( j=${i}+1; j<${outermax};


j+

+ )); do printf "%-2s" ${symbols[($i+$j)%2]} done printf "\n" done

Листинг 4.12 инициализира някои променливи, последвани от вложен цикъл.


Външният цикъл се „контролира“ от променливата на цикъла i, докато вътрешният
цикъл (който зависи от стойността на i) се „контролира“ от променливата на цикъла j.
Забележете как следният кодов фрагмент отпечатва редуващи се символи в масива
символи , в зависимост от това дали стойността на $i + $j е четна или нечетна:
Machine Translated by Google

printf "%-2s" ${символи[($i+$j)%2]}

Можете лесно да обобщите този код: ако масивът от символи съдържа arrlength
елементи, тогава заменете предходния кодов фрагмент със следния:

printf "%-2s" ${symbols[($i+$j)% $arrlength]}

Стартирайте кода в листинг 4.12 и ще видите следния резултат:

@#
@@#@
#@#@@#
@#@#@#@#
@#@#@#@#@
#@#@#@@#@#@
#@#@#@#@#@@#@
#@#@#@#@@#@#@
#@@#@

ИЗПОЛЗВАНЕ НА WHILE LOOP

Листинг 4.13 показва съдържанието на while1.sh , което илюстрира как да се използва


цикъл while за преминаване през набор от числа.

ЛИСТИНГ 4.13: while1.sh

x=0

x=`expr $x + 1` echo "нов x:


$x"

while (true) do echo "x


=
$x" x=`expr $x + 1`

ако [$x -gt 4]


Machine Translated by Google

тогава
прекъсвам
фи
Свършен

Листинг 4.13 инициализира променливата x със стойност 0 и след това увеличава


нейната стойност и отпечатва новата й стойност (която е 1).
Следващата част от листинг 4.13 е цикъл while , който показва стойността на x и
след това увеличава нейната стойност. След това оператор if проверява дали
стойността на x е по-голяма от 4; ако това е вярно, тогава кодът "излиза" от цикъла while .
Стартирайте кода в листинг 4.13 и ще видите следния резултат:

ново x: 1 x
=1
х=2
х=3
х=4

Списък 4.14 илюстрира как да използвате цикъл while за обхождане на текстов


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

ЛИСТИНГ 4.14: upperlowercase.sh

infile="wordfile.txt"
outfile="converted.txt" rm -f $outfile
2>/dev/null

докато чете ред


do
# брой думи на текущия ред wordcount=`echo "$line" |
wc -w` modvalue=`expr $wordcount % 2` if [ $modvalue = 0 ]
then # even: преобразуване в главни букви echo "$line" |
tr '[az]' '[AZ]' >> $outfile else # odd:

конвертиране в малки букви echo "$line" | tr '[AZ]' '[az]' >>


$outfile fi

готово < $infile

Листинг 4.14 инициализира променливите infile и outfile с името на входен файл и


съответно изходен файл и след това извиква командата rm за безусловно премахване
на файла outfile.
Machine Translated by Google

Следващата част от листинг 4.14 е цикъл while , който обработва ред по ред във
входния файл. След това променливата wordcount се инициализира като броя на
думите в текущия ред, а променливата modvalue се инициализира на половината от
стойността на wordcount.
Следващата част от листинг 4.14 е условен блок, който проверява дали modvalue
е четно или нечетно. Ако modvalue е четен, текущият ред се преобразува в главни
букви и след това се добавя към изходния файл. Ако modvalue е странно, текущият ред
се преобразува в малки букви и се добавя към изходния файл.

Списък 4.15 показва съдържанието на wordfile.txt , който е входният файл за


листинг 4.14.

ЛИСТИНГ 4.15: wordfile.txt

абВГДЕ
деф

abc ghi abc

Стартирайте кода в листинг 4.14. Резултатът създава файла


converted.txt, чието съдържание е показано тук:

ABC DEF деф

ABC GHI
абв

ОПИСАНИЯТА WHILE, CASE И IF/ELIF/ELSE/FI

Списък 4.16 показва съдържанието на yesno.sh , което илюстрира как да


комбинирате операторите while, case/esac и if/elif/else/fi в един и същ скрипт на
обвивката.

ОБЯВКА 4.16: yesno.sh

while(true) do echo -n

"Продължете с архивирането (Y/y/N/n): " прочете отговор

case $response in
Machine Translated by Google

n*|N*) continue="false" ;; y*|Y*) continue="true" ;;


*) continue="unknown" ;;

esac

if [ "$proceed" = "true" ] then echo "proceeding with


backup"

break elif [ "$proceed" = "false" ] then echo "canceling


backup"

else

echo "Невалиден отговор" fi

Свършен

Списък 4.16 съдържа цикъл while , който подканва потребителите да въведат главна или малка
буква Y или главна или малка буква n. Входната стойност се присвоява на променливата. Следващата
част от листинг 4.16 е оператор отговор.
case/esac , който съдържа регулярни изрази, които присвояват една от стойностите false, true или
unknown на променливата continue.

Следващата част от листинг 4.16 съдържа кодов блок if/elif/else/fi , който отпечатва подходящо
съобщение, което зависи от стойността на променливата
продължете.

Продължете с архивирането (Y/y/N/n): abc


Невалиден отговор
Продължете с архивирането (Y/y/N/n):
Невалиден отговор
Продължаване с архивиране (Y/y/N/n): ДА, продължаване с
архивиране

ИЗПОЛЗВАНЕ НА ЦИКЪЛ UNTIL

Командата до ви позволява да изпълните поредица от команди толкова дълго


като условие проверява невярно:

до команда do

команди
Свършен
Machine Translated by Google

Списък 4.17 илюстрира как да използвате цикъл unless за преминаване през набор от числа.

ОБЯВКА 4.17: до 1.sh

x="0" до
[ "$x" = "5" ] do x=`expr $x + 1` echo "x:
$x"

done

Листинг 4.17 инициализира променливата x със стойност 0 и след това влиза в цикъл до . Тялото
на цикъла увеличава x и отпечатва стойността му, докато x стане равно на 5, в който момент цикълът
прекратява изпълнението. Стартирайте кода в листинг 4.17 и ще видите следния резултат:

х: 1
х: 2
х: 3
x: 4 x:
5

ДЕФИНИРАНИ ОТ ПОТРЕБИТЕЛЯ ФУНКЦИИ

Bash shell предоставя вградени функции и също така ви позволява да дефинирате свои собствени
функции, което означава, че можете да дефинирате персонализирани функции, които са специфични
за вашите нужди. Ето прости правила за дефиниране на функция в shell скрипт:

• Функционалните блокове започват с ключовата дума функция, последвана от името на


функцията и скоби ( ( ) ). • Кодовият блок във
функция започва с фигурните скоби „{“ и завършва с фигурните скоби „}“.

Следният кодов блок дефинира много проста персонализирана функция, която съдържа
командата echo :

Здравейте()
{
Machine Translated by Google

echo "Здравейте от функция"


}

Можете да дефинирате функцията Hello() директно от командния ред или да поставите


функцията в шел скрипт. Изпълнете функцията, като извикате нейното име:

Здравейте

Резултатът е точно това, което очаквате:

Здравейте от една функция

Предходната дефиниция на функция не прави нищо интересно. За да направите


по-полезна функция, променете тялото на функцията, както е показано тук:

Здравейте()
{
echo "Здравей, $1, как си"
}

Изпълнете модифицираната функция и също така задайте низ, както е показано тук:

Здравей Боб

Резултатът е точно това, което очаквате:

Здравей Боб как си

Следващият пример използва условна логика, за да провери съществуването на a


параметър и след това отпечатва съответното съобщение:

Здравейте()
{
if [ "$1" != "" ] then echo "Hello
$1" else

echo "Моля, посочете име" fi

Изпълнете модифицираната функция, без да указвате низ, както е показано тук:

Здравейте
Machine Translated by Google

Резултатът е точно това, което очаквате:

Моля, посочете име

Следващият пример илюстрира как да дефинирате функция, която итерира


през всички параметри, които се предават на функцията:

Здравейте()
{
докато [ "$1" != "" ] правете echo "hello
$1"
shift

Свършен

Здравей abc

Поставете предходния код в скрипт на обвивка и след като направите обвивката


изпълним скрипт, стартирайте кода, за да видите следния резултат:

здравей а
здравей б
здравей c

СЪЗДАВАНЕ НА ПРОСТО МЕНЮ ОТ КОМАНДИ НА SHELL

Листинг 4.18 показва съдържанието на AppendRow.sh , което илюстрира как да


актуализирайте набор от потребители в текстов файл.

ЛИСТИНГ 4.18: AppendRow.sh

DataFile="users.txt"

addUser() {

"
echo -n "Собствено име:
прочетете fname

"
echo -n "Фамилия: прочетете lname

if [ -n $fname -a -n $lname ] тогава


Machine Translated by Google

# добавяне на нов ред към файла echo "$fname $lname"


>> $DataFile else

echo "Моля, въведете непразни стойности" fi

докато (вярно) правя

ехо ""
echo "Списък с потребители"
echo "==============" cat users.txt 2>/
dev/null

ехо "-----------------------------"
echo "Въведете 'a', за да добавите нов потребител" echo
"Въведете 'd', за да изтриете всички потребители"
echo "Въведете 'x', за да излезете от това меню"
ехо "-----------------------------"
ехо

чете отговор случай


$answer в
a|A) addUser ;; d|D) rm
$DataFile 2>/dev/null ;; x|X) прекъсване ;;

esac
Свършен

Списък 4.18 започва с инициализиране на променливата DataFile със стойността


users.txt, която ще бъде актуализирана със стойности на низове, предоставени от
потребителите. След това се дефинира функцията addUser() . Тази функция се изпълнява
в първата опция на кодовия блок case/esac .
Следващият раздел е цикъл while , който показва съдържанието на файла users.txt
(който първоначално е празен). След това набор от ехо инструкции подканва
потребителите да въведат знака x , за да спрат изпълнението на скрипта на обвивката,
или буквата d , за да изтрият всички имена.
Ако потребителите въведат низа x, скриптът на обвивката излиза от цикъла чрез
командата break , което от своя страна прекратява изпълнението на скрипта на
обвивката. Ако потребителите въведат низа d, съдържанието на файла users.txt се
изтрива. Ако потребителите въведат низ a, тогава функцията addUser се извиква за
добавяне на нов потребител. Тази функция подканва за име и фамилия. Ако и двата
низа не са празни, новият потребител се добавя към файла users.txt; в противен случай
се показва подходящо съобщение (т.е. подкана за въвеждане на непразни стойности
както за собственото, така и за фамилното име).
Machine Translated by Google

Примерно извикване на листинг 4.18 е тук, което вече е добавило трима потребители:

Списък на потребителите
==============

абВГДЕ
123 456 888
777
----------------------------

Въведете 'a', за да добавите нов потребител


Въведете „d“, за да изтриете всички потребители
Въведете 'x', за да излезете от това меню
----------------------------

МАСИВИ В BASH

Масивите са налични в много (всички?) езици за програмиране и те също са налични


в bash. Имайте предвид, че едномерният масив е известен като вектор в математиката, а
двумерният масив се нарича матрица; повечето образци на онлайн код обаче използват
думата „масив“ в скриптовете на обвивката.
Списък 4.19 показва съдържанието на Array1.sh , което илюстрира как да дефинирате
масив и да осъществявате достъп до елементи в масив.

ЛИСТИНГ 4.19: Array1.sh

# инициализиране на масива с имена


names[0]="john"
names[1]="nancy"
names[2]="jane"
names[3]="steve"
names[4]="bob"

# показване на първия и втория запис echo "Първи индекс: $


{names[0]}" echo "Втори индекс: ${names[1]}"

Списък 4.19 дефинира масива с имена , който се инициализира с пет низа, започвайки
от индекс 0 до индекс 4. Двата оператора за ехо показват първия и втория елемент в
масива с имена , които са съответно с индекс 0 и 1. Резултатът от листинг 4.19 е тук:

Първи индекс: john


Втори индекс: Нанси

You might also like