Bash скрипты команды
Bash-скрипты: начало / Хабр
Bash-скрипты: начало
Bash-скрипты, часть 2: циклы
Bash-скрипты, часть 3: параметры и ключи командной строки
Bash-скрипты, часть 4: ввод и вывод
Bash-скрипты, часть 5: сигналы, фоновые задачи, управление сценариями
Bash-скрипты, часть 6: функции и разработка библиотек
Bash-скрипты, часть 7: sed и обработка текстов
Bash-скрипты, часть 8: язык обработки данных awk
Bash-скрипты, часть 9: регулярные выражения
Bash-скрипты, часть 10: практические примеры
Bash-скрипты, часть 11: expect и автоматизация интерактивных утилит
Сегодня поговорим о bash-скриптах. Это — сценарии командной строки, написанные для оболочки bash. Существуют и другие оболочки, например — zsh, tcsh, ksh, но мы сосредоточимся на bash. Этот материал предназначен для всех желающих, единственное условие — умение работать в командной строке Linux.
Сценарии командной строки — это наборы тех же самых команд, которые можно вводить с клавиатуры, собранные в файлы и объединённые некоей общей целью. При этом результаты работы команд могут представлять либо самостоятельную ценность, либо служить входными данными для других команд. Сценарии — это мощный способ автоматизации часто выполняемых действий.
Итак, если говорить о командной строке, она позволяет выполнить несколько команд за один раз, введя их через точку с запятой:
pwd ; whoami
На самом деле, если вы опробовали это в своём терминале, ваш первый bash-скрипт, в котором задействованы две команды, уже написан. Работает он так. Сначала команда pwd
выводит на экран сведения о текущей рабочей директории, потом команда whoami
показывает данные о пользователе, под которым вы вошли в систему.
Используя подобный подход, вы можете совмещать сколько угодно команд в одной строке, ограничение — лишь в максимальном количестве аргументов, которое можно передать программе. Определить это ограничение можно с помощью такой команды:
getconf ARG_MAX
Командная строка — отличный инструмент, но команды в неё приходится вводить каждый раз, когда в них возникает необходимость. Что если записать набор команд в файл и просто вызывать этот файл для их выполнения? Собственно говоря, тот файл, о котором мы говорим, и называется сценарием командной строки.
Как устроены bash-скрипты
Создайте пустой файл с использованием команды touch
. В его первой строке нужно указать, какую именно оболочку мы собираемся использовать. Нас интересует bash
, поэтому первая строка файла будет такой:
#!/bin/bash
В других строках этого файла символ решётки используется для обозначения комментариев, которые оболочка не обрабатывает. Однако, первая строка — это особый случай, здесь решётка, за которой следует восклицательный знак (эту последовательность называют шебанг) и путь к bash
, указывают системе на то, что сценарий создан именно для bash
.
Команды оболочки отделяются знаком перевода строки, комментарии выделяют знаком решётки. Вот как это выглядит:
#!/bin/bash # This is a comment pwd whoami
Тут, так же, как и в командной строке, можно записывать команды в одной строке, разделяя точкой с запятой. Однако, если писать команды на разных строках, файл легче читать. В любом случае оболочка их обработает.
Установка разрешений для файла сценария
Сохраните файл, дав ему имя myscript
, и работа по созданию bash-скрипта почти закончена. Сейчас осталось лишь сделать этот файл исполняемым, иначе, попытавшись его запустить, вы столкнётесь с ошибкой Permission denied
.
Попытка запуска файла сценария с неправильно настроенными разрешениями
Сделаем файл исполняемым:
chmod +x ./myscript
Теперь попытаемся его выполнить:
./myscript
После настройки разрешений всё работает как надо.
Успешный запуск bash-скрипта
Вывод сообщений
Для вывода текста в консоль Linux применяется команда echo
. Воспользуемся знанием этого факта и отредактируем наш скрипт, добавив пояснения к данным, которые выводят уже имеющиеся в нём команды:
#!/bin/bash # our comment is here echo "The current directory is:" pwd echo "The user logged in is:" whoami
Вот что получится после запуска обновлённого скрипта.
Вывод сообщений из скрипта
Теперь мы можем выводить поясняющие надписи, используя команду echo
. Если вы не знаете, как отредактировать файл, пользуясь средствами Linux, или раньше не встречались с командой echo
, взгляните на этот материал.
Использование переменных
Переменные позволяют хранить в файле сценария информацию, например — результаты работы команд для использования их другими командами.
Нет ничего плохого в исполнении отдельных команд без хранения результатов их работы, но возможности такого подхода весьма ограничены.
Существуют два типа переменных, которые можно использовать в bash-скриптах:
- Переменные среды
- Пользовательские переменные
Переменные среды
Иногда в командах оболочки нужно работать с некими системными данными. Вот, например, как вывести домашнюю директорию текущего пользователя:
#!/bin/bash # display user home echo "Home for the current user is: $HOME"
Обратите внимание на то, что мы можем использовать системную переменную $HOME
в двойных кавычках, это не помешает системе её распознать. Вот что получится, если выполнить вышеприведённый сценарий.
Использование переменной среды в сценарии
А что если надо вывести на экран значок доллара? Попробуем так:
echo "I have $1 in my pocket"
Система обнаружит знак доллара в строке, ограниченной кавычками, и решит, что мы сослались на переменную. Скрипт попытается вывести на экран значение неопределённой переменной $1
. Это не то, что нам нужно. Что делать?
В подобной ситуации поможет использование управляющего символа, обратной косой черты, перед знаком доллара:
echo "I have \$1 in my pocket"
Теперь сценарий выведет именно то, что ожидается.
Использование управляющей последовательности для вывода знака доллара
Пользовательские переменные
В дополнение к переменным среды, bash-скрипты позволяют задавать и использовать в сценарии собственные переменные. Подобные переменные хранят значение до тех пор, пока не завершится выполнение сценария.
Как и в случае с системными переменными, к пользовательским переменным можно обращаться, используя знак доллара:
#!/bin/bash # testing variables grade=5 person="Adam" echo "$person is a good boy, he is in grade $grade"
Вот что получится после запуска такого сценария.
Пользовательские переменные в сценарии
Подстановка команд
Одна из самых полезных возможностей bash-скриптов — это возможность извлекать информацию из вывода команд и назначать её переменным, что позволяет использовать эту информацию где угодно в файле сценария.
Сделать это можно двумя способами.
- С помощью значка обратного апострофа «`»
- С помощью конструкции
$()
Используя первый подход, проследите за тем, чтобы вместо обратного апострофа не ввести одиночную кавычку. Команду нужно заключить в два таких значка:
mydir=`pwd`
При втором подходе то же самое записывают так:
mydir=$(pwd)
А скрипт, в итоге, может выглядеть так:
#!/bin/bash mydir=$(pwd) echo $mydir
В ходе его работы вывод команды pwd
будет сохранён в переменной mydir
, содержимое которой, с помощью команды echo
, попадёт в консоль.
Скрипт, сохраняющий результаты работы команды в переменной
Математические операции
Для выполнения математических операций в файле скрипта можно использовать конструкцию вида $((a+b))
:
#!/bin/bash var1=$(( 5 + 5 )) echo $var1 var2=$(( $var1 * 2 )) echo $var2
Математические операции в сценарии
Управляющая конструкция if-then
В некоторых сценариях требуется управлять потоком исполнения команд. Например, если некое значение больше пяти, нужно выполнить одно действие, в противном случае — другое. Подобное применимо в очень многих ситуациях, и здесь нам поможет управляющая конструкция if-then
. В наиболее простом виде она выглядит так:
if команда then команды fi
А вот рабочий пример:
#!/bin/bash if pwd then echo "It works" fi
В данном случае, если выполнение команды pwd
завершится успешно, в консоль будет выведен текст «it works».
Воспользуемся имеющимися у нас знаниями и напишем более сложный сценарий. Скажем, надо найти некоего пользователя в /etc/passwd
, и если найти его удалось, сообщить о том, что он существует.
#!/bin/bash user=likegeeks if grep $user /etc/passwd then echo "The user $user Exists" fi
Вот что получается после запуска этого скрипта.
Поиск пользователя
Здесь мы воспользовались командой grep
для поиска пользователя в файле /etc/passwd
. Если команда grep
вам незнакома, её описание можно найти здесь.
В этом примере, если пользователь найден, скрипт выведет соответствующее сообщение. А если найти пользователя не удалось? В данном случае скрипт просто завершит выполнение, ничего нам не сообщив. Хотелось бы, чтобы он сказал нам и об этом, поэтому усовершенствуем код.
Управляющая конструкция if-then-else
Для того, чтобы программа смогла сообщить и о результатах успешного поиска, и о неудаче, воспользуемся конструкцией if-then-else
. Вот как она устроена:
if команда then команды else команды fi
Если первая команда возвратит ноль, что означает её успешное выполнение, условие окажется истинным и выполнение не пойдёт по ветке else
. В противном случае, если будет возвращено что-то, отличающееся от нуля, что будет означать неудачу, или ложный результат, будут выполнены команды, расположенные после else
.
Напишем такой скрипт:
#!/bin/bash user=anotherUser if grep $user /etc/passwd then echo "The user $user Exists" else echo "The user $user doesn’t exist" fi
Его исполнение пошло по ветке else
.
Запуск скрипта с конструкцией if-then-else
Ну что же, продолжаем двигаться дальше и зададимся вопросом о более сложных условиях. Что если надо проверить не одно условие, а несколько? Например, если нужный пользователь найден, надо вывести одно сообщение, если выполняется ещё какое-то условие — ещё одно сообщение, и так далее. В подобной ситуации нам помогут вложенные условия. Выглядит это так:
if команда1 then команды elif команда2 then команды fi
Если первая команда вернёт ноль, что говорит о её успешном выполнении, выполнятся команды в первом блоке then
, иначе, если первое условие окажется ложным, и если вторая команда вернёт ноль, выполнится второй блок кода.
#!/bin/bash user=anotherUser if grep $user /etc/passwd then echo "The user $user Exists" elif ls /home then echo "The user doesn’t exist but anyway there is a directory under /home" fi
В подобном скрипте можно, например, создавать нового пользователя с помощью команды useradd
, если поиск не дал результатов, или делать ещё что-нибудь полезное.
Сравнение чисел
В скриптах можно сравнивать числовые значения. Ниже приведён список соответствующих команд.
n1 -eq n2
Возвращает истинное значение, еслиn1
равноn2
.n1 -ge n2
Возвращает истинное значение, еслиn1
больше или равноn2
.n1 -gt n2
Возвращает истинное значение, еслиn1
большеn2
.n1 -le n2
Возвращает истинное значение, еслиn1
меньше или равноn2
.n1 -lt n2
Возвращает истинное значение, если n1 меньшеn2
.n1 -ne n2
Возвращает истинное значение, еслиn1
не равноn2
.
В качестве примера опробуем один из операторов сравнения. Обратите внимание на то, что выражение заключено в квадратные скобки.
#!/bin/bash val1=6 if [ $val1 -gt 5 ] then echo "The test value $val1 is greater than 5" else echo "The test value $val1 is not greater than 5" fi
Вот что выведет эта команда.
Сравнение чисел в скриптах
Значение переменной val1
больше чем 5, в итоге выполняется ветвь then
оператора сравнения и в консоль выводится соответствующее сообщение.
Сравнение строк
В сценариях можно сравнивать и строковые значения. Операторы сравнения выглядят довольно просто, однако у операций сравнения строк есть определённые особенности, которых мы коснёмся ниже. Вот список операторов.
str1 = str2
Проверяет строки на равенство, возвращает истину, если строки идентичны.
str1 != str2
Возвращает истину, если строки не идентичны.str1 < str2
Возвращает истину, еслиstr1
меньше, чемstr2
.str1 > str2
Возвращает истину, еслиstr1
больше, чемstr2
.-n str1
Возвращает истину, если длинаstr1
больше нуля.-z str1
Возвращает истину, если длинаstr1
равна нулю.
Вот пример сравнения строк в сценарии:
#!/bin/bash user ="likegeeks" if [$user = $USER] then echo "The user $user is the current logged in user" fi
В результате выполнения скрипта получим следующее.
Сравнение строк в скриптах
Вот одна особенность сравнения строк, о которой стоит упомянуть. А именно, операторы «>» и «<» необходимо экранировать с помощью обратной косой черты, иначе скрипт будет работать неправильно, хотя сообщений об ошибках и не появится. Скрипт интерпретирует знак «>» как команду перенаправления вывода.
Вот как работа с этими операторами выглядит в коде:
#!/bin/bash val1=text val2="another text" if [ $val1 \> $val2 ] then echo "$val1 is greater than $val2" else echo "$val1 is less than $val2" fi
Вот результаты работы скрипта.
Сравнение строк, выведенное предупреждение
Обратите внимание на то, что скрипт, хотя и выполняется, выдаёт предупреждение:
./myscript: line 5: [: too many arguments
Для того, чтобы избавиться от этого предупреждения, заключим $val2
в двойные кавычки:
#!/bin/bash val1=text val2="another text" if [ $val1 \> "$val2" ] then echo "$val1 is greater than $val2" else echo "$val1 is less than $val2" fi
Теперь всё работает как надо.
Сравнение строк
Ещё одна особенность операторов «>» и «<» заключается в том, как они работают с символами в верхнем и нижнем регистрах. Для того, чтобы понять эту особенность, подготовим текстовый файл с таким содержимым:
Likegeeks likegeeks
Сохраним его, дав имя myfile
, после чего выполним в терминале такую команду:
sort myfile
Она отсортирует строки из файла так:
likegeeks Likegeeks
Команда sort
, по умолчанию, сортирует строки по возрастанию, то есть строчная буква в нашем примере меньше прописной. Теперь подготовим скрипт, который будет сравнивать те же строки:
#!/bin/bash val1=Likegeeks val2=likegeeks if [ $val1 \> $val2 ] then echo "$val1 is greater than $val2" else echo "$val1 is less than $val2" fi
Если его запустить, окажется, что всё наоборот — строчная буква теперь больше прописной.
Команда sort и сравнение строк в файле сценария
В командах сравнения прописные буквы меньше строчных. Сравнение строк здесь выполняется путём сравнения ASCII-кодов символов, порядок сортировки, таким образом, зависит от кодов символов.
Команда sort
, в свою очередь, использует порядок сортировки, заданный в настройках системного языка.
Проверки файлов
Пожалуй, нижеприведённые команды используются в bash-скриптах чаще всего. Они позволяют проверять различные условия, касающиеся файлов. Вот список этих команд.
-d file
Проверяет, существует ли файл, и является ли он директорией.-e file
Проверяет, существует ли файл.-f file
Проверяет, существует ли файл, и является ли он файлом.-r file
Проверяет, существует ли файл, и доступен ли он для чтения.-s file П
роверяет, существует ли файл, и не является ли он пустым.-w file
Проверяет, существует ли файл, и доступен ли он для записи.-x file
Проверяет, существует ли файл, и является ли он исполняемым.file1 -nt file2
Проверяет, новее лиfile1
, чемfile2
.file1 -ot file2
Проверяет, старше лиfile1
, чемfile2
.-O file
Проверяет, существует ли файл, и является ли его владельцем текущий пользователь.-G file
Проверяет, существует ли файл, и соответствует ли его идентификатор группы идентификатору группы текущего пользователя.
Эти команды, как впрочем, и многие другие рассмотренные сегодня, несложно запомнить. Их имена, являясь сокращениями от различных слов, прямо указывают на выполняемые ими проверки.
Опробуем одну из команд на практике:
#!/bin/bash mydir=/home/likegeeks if [ -d $mydir ] then echo "The $mydir directory exists" cd $ mydir ls else echo "The $mydir directory does not exist" fi
Этот скрипт, для существующей директории, выведет её содержимое.
Вывод содержимого директории
Полагаем, с остальными командами вы сможете поэкспериментировать самостоятельно, все они применяются по тому же принципу.
Итоги
Сегодня мы рассказали о том, как приступить к написанию bash-скриптов и рассмотрели некоторые базовые вещи. На самом деле, тема bash-программирования огромна. Эта статья является переводом первой части большой серии из 11 материалов. Если вы хотите продолжения прямо сейчас — вот список оригиналов этих материалов. Для удобства сюда включён и тот, перевод которого вы только что прочли.
- Bash Script Step By Step — здесь речь идёт о том, как начать создание bash-скриптов, рассмотрено использование переменных, описаны условные конструкции, вычисления, сравнения чисел, строк, выяснение сведений о файлах.
- Bash Scripting Part 2, Bash the awesome — тут раскрываются особенности работы с циклами for и while.
- Bash Scripting Part 3, Parameters & options — этот материал посвящён параметрам командной строки и ключам, которые можно передавать скриптам, работе с данными, которые вводит пользователь, и которые можно читать из файлов.
- Bash Scripting Part 4, Input & Output — здесь речь идёт о дескрипторах файлов и о работе с ними, о потоках ввода, вывода, ошибок, о перенаправлении вывода.
- Bash Scripting Part 5, Sighals & Jobs — этот материал посвящён сигналам Linux, их обработке в скриптах, запуску сценариев по расписанию.
- Bash Scripting Part 6, Functions — тут можно узнать о создании и использовании функций в скриптах, о разработке библиотек.
- Bash Scripting Part 7, Using sed — эта статья посвящена работе с потоковым текстовым редактором sed.
- Bash Scripting Part 8, Using awk — данный материал посвящён программированию на языке обработки данных awk.
- Bash Scripting Part 9, Regular Expressions — тут можно почитать об использовании регулярных выражений в bash-скриптах.
- Bash Scripting Part 10, Practical Examples — здесь приведены приёмы работы с сообщениями, которые можно отправлять пользователям, а так же методика мониторинга диска.
- Bash Scripting Part 11, Expect Command — этот материал посвящён средству Expect, с помощью которого можно автоматизировать взаимодействие с интерактивными утилитами. В частности, здесь идёт речь об expect-скриптах и об их взаимодействии с bash-скриптами и другими программами.
Полагаем, одно из ценных свойств этой серии статей заключается в том, что она, начинаясь с самого простого, подходящего для пользователей любого уровня, постепенно ведёт к довольно серьёзным темам, давая шанс всем желающим продвинуться в деле создания сценариев командной строки Linux.
Уважаемые читатели! Просим гуру bash-программирования рассказать о том, как они добрались до вершин мастерства, поделиться секретами, а от тех, кто только что написал свой первый скрипт, ждём впечатлений.
Bash-скрипты, часть 10: практические примеры / Хабр
Bash-скрипты: начало
Bash-скрипты, часть 2: циклы
Bash-скрипты, часть 3: параметры и ключи командной строки
Bash-скрипты, часть 4: ввод и вывод
Bash-скрипты, часть 5: сигналы, фоновые задачи, управление сценариями
Bash-скрипты, часть 6: функции и разработка библиотек
Bash-скрипты, часть 7: sed и обработка текстов
Bash-скрипты, часть 8: язык обработки данных awk
Bash-скрипты, часть 9: регулярные выражения
Bash-скрипты, часть 10: практические примеры
Bash-скрипты, часть 11: expect и автоматизация интерактивных утилит
В предыдущих материалах мы обсуждали различные аспекты разработки bash-скриптов, говорили о полезных инструментах, но до сих пор рассматривали лишь небольшие фрагменты кода. Пришло время более масштабных проектов. А именно, здесь вы найдёте два примера. Первый — скрипт для отправки сообщений, второй пример — скрипт, выводящий сведения об использовании дискового пространства.
Главная ценность этих примеров для тех, кто изучает bash, заключается в методике разработки. Когда перед программистом встаёт задача по автоматизации чего бы то ни было, его путь редко бывает прямым и быстрым. Задачу надо разбить на части, найти средства решения каждой из подзадач, а потом собрать из частей готовое решение.
Отправка сообщений в терминал пользователя
В наши дни редко кто прибегает к одной из возможностей Linux, которая позволяет общаться, отправляя сообщения в терминалы пользователей, вошедших в систему. Сама по себе команда отправки сообщений, write
, довольно проста. Для того, чтобы ей воспользоваться, достаточно знать имя пользователя и имя его терминала. Однако, для успешной отправки сообщения, помимо актуальных данных о пользователе и терминале, надо знать, вошёл ли пользователь в систему, не запретил ли он запись в свой терминал. В результате, перед отправкой сообщения нужно выполнить несколько проверок.
Как видите, задача: «отправить сообщение», при ближайшем рассмотрении, оказалась задачей: «проверить возможность отправки сообщения, и, если нет препятствий, отправить его». Займёмся решением задачи, то есть — разработкой bash-скрипта.
▍Команды who и mesg
Ядром скрипта являются несколько команд, которые мы ещё не обсуждали. Всё остальное должно быть вам знакомо по предыдущим материалам.
Первое, что нам тут понадобится — команда who
. Она позволяет узнать сведения о пользователях, работающих в системе. В простейшем виде её вызов выглядит так:
$ who
Результаты вызова команды who
В каждой строчке, которую выводит команда who
, нас интересуют первых два показателя — имя пользователя и сведения о его терминале.
По умолчанию запись в терминал разрешена, но пользователь может, с помощью команды mesg
, запретить отправку ему сообщений. Таким образом, прежде чем пытаться что-то кому-то отправить, неплохо будет проверить, разрешена ли отправка сообщений. Если нужно узнать собственный статус, достаточно ввести команду mesg
без параметров:
$ mesg
Команда mesg
В данном случае команда вывела «is y», это значит, что пользователь, под которым мы работаем в системе, может принимать сообщения, отправленные в его терминал. В противном случае mesg
выведет «is n».
Для проверки того, разрешена ли отправка сообщений какому-то другому пользователю, можно использовать уже знакомую вам команду who
с ключом -T
:
$ who -T
При этом проверка возможна только для пользователей, которые вошли в систему. Если такая команда, после имени пользователя, выведет чёрточку (-), это означает, что пользователь запретил запись в свой терминал, то есть, сообщения ему отправлять нельзя. О том, что пользователю можно отправлять сообщения, говорит знак «плюс» (+).
Если у вас приём сообщений отключён, а вы хотите позволить другим пользователям отправлять вам сообщения, можно воспользоваться такой командой:
$ mesg y
Включение приёма сообщений от других пользователей
После включения приёма сообщений mesg
возвращает «is y».
Конечно, для обмена сообщениями нужны два пользователя, поэтому мы, после обычного входа в систему, подключились к компьютеру по ssh. Теперь можно поэкспериментировать.
▍Команда write
Основной инструмент для обмена сообщениями между пользователями, вошедшими в систему — команда write
. Если приём сообщений у пользователя разрешён, с помощью этой команды ему можно отправлять сообщения, используя его имя и сведения о терминале.
Обратите внимание на то, что с помощью write
можно отправлять сообщения пользователям, вошедшим в виртуальную консоль. Пользователи, которые работают в графическом окружении (KDE, Gnome, Cinnamon, и так далее), не могут получать подобные сообщения.
Итак, мы, работая под пользователем likegeeks
, инициируем сеанс связи с пользователем testuser
, который работает в терминале pts/1
, следующим образом:
$ write testuser pts/1
Проверка возможности отправки сообщений и отправка сообщения
После выполнения вышеуказанной команды перед нами окажется пустая строка, в которую нужно ввести первую строку сообщения. Нажав клавишу ENTER
, мы можем ввести следующую строку сообщения. После того, как ввод текста завершён, окончить сеанс связи можно, воспользовавшись комбинацией клавиш CTRL + D
, которая позволяет ввести символ конца файла.
Вот что увидит в своём терминале пользователь, которому мы отправили сообщение.
Новое сообщение, пришедшее в терминал
Получатель может понять от кого пришло сообщение, увидеть время, когда оно было отправлено. Обратите внимание на признак конца файла, EOF
, расположенный в нижней части окна терминала. Он указывает на окончание текста сообщения.
Полагаем, теперь у нас есть всё необходимое для того, чтобы автоматизировать отправку сообщений с помощью сценария командной строки.
▍Создание скрипта для отправки сообщений
Прежде чем заниматься отправкой сообщений, нужно определить, вошёл ли интересующий нас пользователь в систему. Сделать это можно с помощью такой команды:
logged_on=$(who | grep -i -m 1 $1 | awk '{print $1}')
Здесь результаты работы команды who
передаются команде grep
. Ключ -i
этой команды позволяет игнорировать регистр символов. Ключ -m 1
включён в вызов команды на тот случай, если пользователь вошёл в систему несколько раз. Эта команда либо не выведет ничего, либо выведет имя пользователя (его мы укажем при вызове скрипта, оно попадёт в позиционную переменную $1
), соответствующее первому найденному сеансу. Вывод grep
мы передаём awk
. Эта команда, опять же, либо не выведет ничего, либо выведет элемент, записанный в собственную переменную $1
, то есть — имя пользователя. В итоге то, что получилось, попадает в переменную logged_on
.
Теперь надо проверить переменную logged_on
, посмотреть, есть ли в ней что-нибудь:
if [ -z $logged_on ] then echo "$1 is not logged on." echo "Exit" exit fi
Если вы не вполне уверенно чувствуете себя, работая с конструкцией if
, взгляните на этот материал.
Скрипт, содержащий вышеописанный код, сохраним в файле senderscript
и вызовем, передав ему, в качестве параметра командной строки, имя пользователя testuser
.
Проверка статуса пользователя
Тут мы проверяем, является ли logged_on
переменной с нулевой длиной. Если это так, нам сообщат о том, что в данный момент пользователь в систему не вошёл и скрипт завершит работу с помощью команды exit
. В противном случае выполнение скрипта продолжится.
▍Проверка возможности записи в терминал пользователя
Теперь надо проверить, принимает ли пользователь сообщения. Для этого понадобится такая конструкция, похожая на ту, которую мы использовали выше:
allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}') if [ $allowed != "+" ] then echo "$1 does not allowing messaging." echo "Exit" exit fi
Проверка возможности отправки сообщений пользователю
Сначала мы вызываем команду who
с ключом -T
. В строке сведений о пользователе, который может принимать сообщения, окажется знак «плюс» (+), если же пользователь принимать сообщения не может — там будет чёрточка (-). То, что получилось после вызова who
, передаётся grep
, а потом — awk
, формируя переменную allowed
.
Далее, используя условный оператор, мы проверяем то, что оказалось в переменной allowed
. Если знака «плюс» в ней нет, сообщим о том, что отправка сообщений пользователю запрещена и завершим работу. В противном случае выполнение сценария продолжится.
▍Проверка правильности вызова скрипта
Первым параметром скрипта является имя пользователя, которому мы хотим отправить сообщение. Вторым — текст сообщения, в данном случае — состоящий из одного слова. Для того, чтобы проверить, передано ли скрипту сообщение для отправки, воспользуемся таким кодом:
if [ -z $2 ] then echo "No message parameter included." echo "Exit" exit fi
Проверка параметров командной строки, указанных при вызове скрипта
Тут, если при вызове скрипта ему не было передано сообщение для отправки, мы сообщаем об этом и завершаем работу. В противном случае — идём дальше.
▍Получение сведений о терминале пользователя
Прежде чем отправить пользователю сообщение, нужно получить сведения о терминале, в котором он работает и сохранить имя терминала в переменной. Делается это так:
terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')
Теперь, после того, как все необходимые данные собраны, осталось лишь отправить сообщение:
echo $2 | write $logged_on $terminal
Вызов готового скрипта выглядит так:
$ ./senderscript testuser welcome
Успешная отправка сообщения с помощью bash-скрипта
Как видно, всё работает как надо. Однако, с помощью такого сценария можно отправлять лишь сообщения, состоящие из одного слова. Хорошо бы получить возможность отправлять более длинные сообщения.
▍Отправка длинных сообщений
Попробуем вызвать сценарий senderscript
, передав ему сообщение, состоящее из нескольких слов:
$ ./senderscript likegeeks welcome to shell scripting
Попытка отправки длинного сообщения
Как видно, отправлено было лишь первое слово. Всё дело в том, что каждое слово сообщения воспринимается внутри скрипта как отдельная позиционная переменная. Для того, чтобы получить возможность отправки длинных сообщений, обработаем параметры командной строки, переданные сценарию, воспользовавшись командой shift
и циклом while
.
shift while [ -n "$1" ] do whole_message=$whole_message' '$1 shift done
После этого, в команде отправки сообщения, воспользуемся, вместо применяемой ранее позиционной переменной $2
, переменной whole_message
:
echo $whole_message | write $logged_on $terminal
Вот полный текст сценария:
#!/bin/bash logged_on=$(who | grep -i -m 1 $1 | awk '{print $1}') if [ -z $logged_on ] then echo "$1 is not logged on." echo "Exit" exit fi allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}') if [ $allowed != "+" ] then echo "$1 does not allowing messaging." echo "Exit" exit fi if [ -z $2 ] then echo "No message parameter included. " echo "Exit" exit fi terminal=$(who | grep -i -m 1 $1 | awk '{print $2}') shift while [ -n "$1" ] do whole_message=$whole_message' '$1 shift done echo $whole_message | write $logged_on $terminal
Испытаем его:
$ ./senderscript likegeeks welcome to shell scripting
Успешная отправка длинного сообщения:
Длинное сообщение успешно дошло до адресата. Теперь рассмотрим следующий пример.
Скрипт для мониторинга дискового пространства
Сейчас мы собираемся создать сценарий командной строки, который предназначен для поиска в заданных директориях первой десятки папок, на которые приходится больше всего дискового пространства. В этом нам поможет командаdu
, которая выводит сведения о том, сколько места на диске занимают файлы и папки. По умолчанию она выводит сведения лишь о директориях, с ключом -a
в отчёт попадают и отдельные файлы. Её ключ -s
позволяет вывести сведения о размерах директорий. Эта команда позволяет, например, узнать объём дискового пространства, который занимают данные некоего пользователя. Вот как выглядит вызов этой команды:
$ du -s /var/log/
Для наших целей лучше подойдёт ключ -S
(заглавная S), так как он позволяет получить сведения как по корневой папке, так и по вложенным в неё директориям:
$ du -S /var/log/
Вызов команды du с ключами -s и -S
Нам нужно найти директории, на которые приходится больше всего дискового пространства, поэтому список, который выдаёт du
, надо отсортировать, воспользовавшись командой sort
:
$ du -S /var/log/ | sort -rn
Отсортированный список объектов
Ключ -n
указывает команде на то, что нужна числовая сортировка, ключ -r —
на обратный порядок сортировки (самое большое число окажется в начале списка). Полученные данные вполне подходят для наших целей.
Для того, чтобы ограничить полученный список первыми десятью записями, воспользуемся потоковым редактором sed
, который позволит удалить из полученного списка все строки, начиная с одиннадцатой. Следующий шаг — добавить к каждой полученной строке её номер. Тут также поможет sed
, а именно — его команда N
:
sed '{11,$D; =}' | sed 'N; s/\n/ /' |
Приведём полученные данные в порядок, воспользовавшись awk
. Передадим awk
то, что получилось после обработки данных с помощью sed
, применив, как и в других случаях, конвейер, и выведем полученные данные с помощью команды printf
:
awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
В начале строки выводится её номер, потом идёт двоеточие и знак табуляции, далее — объём дискового пространства, следом — ещё один знак табуляции и имя папки.
Соберём вместе всё то, о чём мы говорили:
$ du -S /var/log/ | sort -rn | sed '{11,$D; =}' | sed 'N; s/\n/ /' | awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
Вывод сведений о дисковом пространстве
Для того, чтобы повысить эффективность работы скрипта, код которого вы совсем скоро увидите, реализуем возможность получения данных сразу по нескольким директориям. Для этого создадим переменную MY_DIRECTORIES
и внесём в неё список интересующих нас директорий:
MY_DIRECTORIES="/home /var/log"
Переберём список с помощью цикла for
и вызовем вышеописанную последовательность команд для каждого элемента списка. Вот что получилось в результате:
#!/bin/bash MY_DIRECTORIES="/home /var/log" echo "Top Ten Disk Space Usage" for DIR in $MY_DIRECTORIES do echo "The $DIR Directory:" du -S $DIR 2>/dev/null | sort -rn | sed '{11,$D; =}' | sed 'N; s/\n/ /' | awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}' done exit
Получение сведений о нескольких директориях
Как видите, скрипт выводит, в виде удобного списка, сведения о директориях, список которых хранится в MY_DIRECTORIES
.
Команду du
в этом скрипте можно вызвать с другими ключами, полученный список объектов вполне можно отфильтровать, в целом — тут открывается широкий простор для самостоятельных экспериментов. В результате, вместо работы со списком папок, можно, например, найти самые большие файлы с расширением .log,
или реализовать более сложный алгоритм поиска самых больших (или самых маленьких) файлов и папок.
Итоги
Сегодня мы подробно разобрали пару примеров разработки скриптов. Тут хотелось бы напомнить, что наша главная цель — не в том, чтобы написать скрипт для отправки сообщений с помощью команды write
, или сценарий, который помогает в поиске файлов и папок, занимающих много места на диске, а в описании самого процесса разработки. Освоив эти примеры, поэкспериментировав с ними, возможно — дополнив их или полностью переработав, вы научитесь чему-то новому, улучшите свои навыки разработки bash-скриптов.
На сегодня это всё. В следующий раз поговорим об автоматизации работы с интерактивными утилитами с помощью expect.
Уважаемые читатели! Есть ли у вас на примете несложные (а может быть и сложные, но понятные) bash-скрипты, разбор которых будет полезен новичкам?
25 основных команд и создание пользовательских команд
Краткое примечание: Все, что заключено в [ ]
, означает, что это необязательно. Некоторые команды можно использовать без параметров или указания файлов.
ls — Список содержимого каталога
ls
— вероятно, самая распространенная команда. Много раз вы будете работать в каталоге, и вам нужно знать, какие файлы там находятся. Команда ls позволяет быстро просмотреть все файлы в указанном каталоге.
echo — выводит текст в окно терминала
echo
выводит текст в окно терминала и обычно используется в сценариях оболочки и пакетных файлах для вывода текста состояния на экран или в компьютерный файл. Эхо также особенно полезно для отображения значений переменных среды, которые сообщают оболочке, как вести себя, когда пользователь работает в командной строке или в сценариях.
touch — Создает файл
touch
будет самым простым способом создания новых файлов, но его также можно использовать для изменения временных меток файлов и/или каталогов. Вы можете создать столько файлов, сколько хотите, с помощью одной команды, не беспокоясь о перезаписи файлов с тем же именем.
-
Синтаксис:
touch
[параметры] имя_файла -
Общие параметры: -a, -m, -r, -d
mkdir — Создать каталог
mkdir
— полезная команда, которую можно использовать для создания каталогов. Одновременно может быть создано любое количество каталогов, что может значительно ускорить процесс.
-
Синтаксис:
mkdir
[опция(и)] имя(я) каталога -
Общие параметры: -m, -p, -v
grep — поиск
grep
используется для поиска в тексте шаблонов, указанных пользователем. Это одна из самых полезных и мощных команд. Часто бывают ситуации, когда вам нужно найти определенную строку или шаблон в файле, но вы не знаете, с чего начать поиск, и именно здесь grep чрезвычайно полезен.
-
Синтаксис:
grep
[параметр(ы)] шаблон [файл(ы)] -
Общие параметры: -i, -c, -n
man — Распечатайте руководство или получите справку по команде
Команда man
— это ваше руководство, и оно очень полезно, когда вам нужно выяснить, что делает команда. Например, если вы не знали, что делает команда rmdir, вы можете узнать это с помощью команды man.
-
Синтаксис:
человек
[вариант(ы)] ключевое слово(я) -
Общие параметры: -w, -f, -b
pwd — Печать рабочего каталога
pwd
используется для печати текущего каталога, в котором вы находитесь. Например, если у вас работает несколько терминалов и вам нужно запомнить точный каталог, в котором вы работаете. , тогда pwd сообщит вам.
cd — Изменить каталог
cd
изменит каталог, в котором вы находитесь, чтобы вы могли получать информацию, манипулировать, читать и т. д. различные файлы и каталоги в вашей системе.
mv — Переместить или переименовать каталог
mv
используется для перемещения или переименования каталогов. Без этой команды вам пришлось бы индивидуально переименовывать каждый файл, что утомительно. mv
позволяет выполнять пакетное переименование файлов, что может сэкономить вам массу времени.
rmdir — Удалить каталог
rmdir
удалит пустые каталоги. Это может помочь очистить место на вашем компьютере и упорядочить файлы и папки. Важно отметить, что существует два способа удаления каталогов: rm и rmdir. Разница между ними заключается в том, что rmdir удалит только пустые каталоги, тогда как rm удалит каталоги и файлы независимо от того, содержат они данные или нет.
locate — найти определенный файл или каталог
Это самый простой способ найти файл или каталог. Вы можете расширить область поиска, если не знаете, что именно ищете, или сузить область поиска, используя подстановочные знаки или регулярные выражения.
-
Синтаксис:
locate
[параметр(ы)] имя_файла(ов) -
Общие параметры: -q, -n, -i
Понравилась статья? Прокрутите вниз, чтобы подписаться на нашу бесплатную новостную рассылку, выходящую раз в два месяца.
less — просмотреть содержимое текстового файла
Команда less
позволяет просматривать файлы, не открывая редактор. Это быстрее в использовании, и нет никаких шансов, что вы непреднамеренно измените файл.
-
Синтаксис:
меньше
имя_файла -
Общие параметры: -e, -f, -n
compgen — показывает все доступные команды, псевдонимы и функции.
compgen
— удобная команда, когда вам нужно сослаться на все доступные команды, псевдонимы и функции.
-
Синтаксис:
compgen
[опция(и)] -
Общие параметры: -a, -c, -d
> — redirect stdout
Символ >
является оператором перенаправления. Это берет вывод предыдущей команды, который вы обычно видите в терминале, и отправляет его в файл, который вы ему даете. В качестве примера возьмем эхо «содержимое файла1» > файл1. Здесь он создает файл с именем file1 и помещает в него эхо-строку.
-
Синтаксис:
>
-
Общие опции: нет данных
cat — чтение файла, создание файла и объединение файлов
cat
— одна из наиболее универсальных команд, выполняющая три основные функции: отображение их, объединение их копий и создание новых.
| — Pipe
Pipe берет стандартный вывод одной команды и передает его в качестве ввода другой.
-
Синтаксис:
|
-
Общие опции: нет данных
head — чтение начала файла
По умолчанию команда head
отображает первые 10 строк файла. Бывают случаи, когда вам может понадобиться быстро просмотреть несколько строк в файле, и head позволяет вам это сделать. Типичный пример того, когда вы захотите использовать head, — это когда вам нужно проанализировать журналы или текстовые файлы, которые часто изменяются.
tail — прочитать конец файла
По умолчанию команда tail
отображает последние 10 строк файла. Бывают случаи, когда вам может понадобиться быстро просмотреть несколько строк в файле, и хвост позволяет вам это сделать. Типичный пример использования tail — анализ журналов или текстовых файлов, которые часто изменяются.
chmod — устанавливает флаг прав доступа к файлу для файла или папки. не имеют доступа. Быстрое решение для этого состоит в том, чтобы использовать чмод
. Разрешения могут быть установлены буквенно-цифровыми символами (u, g, o), а их доступ может быть назначен с помощью w, r, x. И наоборот, вы также можете использовать восьмеричные числа (0-7) для изменения разрешений. Например, chmod
777 my_file
даст доступ всем.
exit — выход из каталога
Команда exit
закрывает окно терминала, завершает выполнение сценария оболочки или выходит из сеанса удаленного доступа SSH.
-
Синтаксис:
выход
-
Общие опции: нет данных
16 команд Bash, которые должны знать специалисты по обработке и анализу данных
Специалистам по обработке данных необходимо иметь общее представление о bash и его командах. Bash, который часто называют терминалом, консолью или командной строкой, представляет собой оболочку Unix, которая может помочь вам перемещаться по вашему компьютеру и выполнять определенные задачи.
В этой статье мы рассмотрим несколько наиболее часто используемых команд bash, которые должен знать каждый специалист по данным.
16 Bash Commands Data Scientists Must Know
- ls Command
- cd Command
- rm Command
- mv Command
- cp Command
- mkdir Command
- pwd Command
- touch Command
- cat Command
- less Command 100007
1. Команда ls
Команда
ls
(список) используется для вывода списка каталогов или файлов. По умолчанию (т. е. при запускеls
без каких-либо параметров) команда вернет каталоги и файлы текущего каталога, исключая любые скрытые файлы. Некоторые из наиболее полезных опций:-
ls -a
: Список всех файлов в текущем каталоге, включая скрытые файлы -
ls -l
: Длинный список всех файлов и их размера в текущем каталоге
Синтаксис
ls [ОПЦИИ] [ФАЙЛЫ]
Пример
Длинный список всех каталогов и файлов (включая скрытые) текущего каталога. Изображение: Скриншот автора.$ ls -la
2. Команда cd
Команда
cd
(сменить каталог) используется для навигации по древовидной структуре каталогов.Синтаксис
каталог cd [OPTIONS]
Команда может принимать только два параметра:
L
, чтобы указать, следует ли переходить по символическим ссылкам, илиP
, чтобы указать, что не следует.Пример
Изменение текущего каталога. Изображение: Скриншот автора.$ cd myproject
3. Команда rm
Команда
rm
(удалить) используется для удаления файлов, каталогов или даже символических ссылок из вашей файловой системы. Некоторые из наиболее полезных опций:-
rm-i
: Удалите все файлы в каталоге, но дайте пользователю подтвердить удаление перед удалением. -
rm-r
: Удалить непустые каталоги, включая все файлы в них. -
rm-f
: Удаление файлов или каталогов без запроса, даже если они защищены от записи — f означает принудительное удаление.
Синтаксис
rm [ОПЦИИ]... ФАЙЛ...
Пример
Принудительное удаление каталога с именем «directoryName». Изображение: Скриншот автора.$ rm -rf имя_каталога
4. Команда mv
Команда
mv
(перемещение) используется для перемещения одного или нескольких каталогов или файлов из одного места в файловой системе в другое.Синтаксис
MV [Параметры] Пункт назначения
-
Источник
может быть один или несколько каталогов или файлов -
Пункт
может быть файл (используется для переименования) или в директоре (для использования для для. перемещение файлов и каталогов в другие каталоги).
Пример
Изображение: снимок экрана сделан автором.# Переименовать файл $ mv файл1.txt файл2.txt # Переместить файл в другую директорию $ mv file1.txt otherDir/
5. cp Command
Cp
— это утилита, позволяющая копировать файлы или каталоги в файловой системе. Вот некоторые из наиболее полезных опций:-
cp -u file1.txt file1_final.txt
: Скопировать содержимоеfile1.txt
вfile1_final.txt
, только если первое (источник) новее второго (назначение). -
cp -R myDir/ myDir_BACKUP
: Copy directories -
cp -p file1.txt file1_final.txt
: Copyfile1.txt
and preserve ownership
Syntax
cp [OPTIONS] SOURCE ... НАЗНАЧЕНИЕ
-
ИСТОЧНИК
может содержать один или несколько каталогов или файлов -
НАЗНАЧЕНИЕ
должен быть одним каталогом или файлом
Пример
Изображение: снимок экрана сделан автором.# Копировать файлы $ cp файл1.txt файл1_final.txt # Копировать каталоги (и сохранить права собственности) $ cp -Rp myDir/ myDirBackup
6. Команда mkdir
Команда mkdir полезна при создании новых каталогов в файловой системе.
Синтаксис
mkdir [ОПЦИЯ] [КАТАЛОГ]
-
КАТАЛОГ
может быть одним или несколькими каталогами
Пример
Создание нового каталога. Изображение: Скриншот автора.# Создать новый каталог с именем myNewDir $ mkdir myNewDir
7. Команда pwd
Команда
pwd
(распечатать рабочий каталог) может использоваться для сообщения абсолютного пути к текущему рабочему каталогу.Пример
Сообщение о пути к текущему рабочему каталогу. Изображение: Скриншот автора.$ в день /Пользователи/администратор
8. Команда touch
Команда
touch
позволяет создавать новые пустые файлы или обновлять отметку времени в существующих файлах или каталогах. Если вы используетеtouch
с уже существующими файлами, то команда просто обновит их метки времени. Если файлы не существуют, то эта команда их просто создаст.Некоторые из наиболее полезных опций:
-
touch -c file1.txt
: Если файлfile1.txt
уже существует, эта команда обновит метки времени файла. В противном случае он ничего не сделает. -
touch -a file1.txt
: Обновляет только отметку времени доступа к файлу. -
touch -m file1.txt
: Обновляет только время модификации файла.
Синтаксис
touch [ОПЦИИ] [ФАЙЛЫ]
Пример
Изображение: Скриншот автора.# Создать новый файл (file1.txt не существует) сенсорный файл1.txt # Обновить время доступа к файлу (file1.txt уже существует) сенсорный -файл1.txt
9. Команда cat
Cat
— очень часто используемая команда, которая позволяет пользователям считывать объединенные файлы или записывать содержимое файлов в стандартный вывод.Некоторые из наиболее полезных опций:
-
cat-n file1.txt
: Показать содержимое файлаfile1.txt
вместе с номерами строк. -
cat-T file1.txt
: Показать содержимое файлаfile1.txt
и различать вкладки и пробелы (вкладки будут отображаться как 9I в выходе)
Синтаксис
CAT [Параметры] [FILE_NAMES]
-
FILE_NAMES
может быть нулевым или более именами файлов
Пример. Пример
.# Показать содержимое файла $HOME/.pip/pip.conf кот $HOME/.pip/pip.conf # Добавляем содержимое файла file1.txt в файл file2.txt cat file1.txt >> file2.txt
Методы обработки данных для освоенияВажные формулы Power BI для динамических фильтров, которые необходимо знать
10. Команда less
Команда
less
позволяет отображать содержимое файла по одной странице за раз.Меньше
не будет читать весь файл при вызове; таким образом, это приводит к более быстрому времени загрузки.Некоторые из наиболее полезных опций:
-
less-N file1.txt
: Показать содержимое (первая страница) файлаfile1.txt
и показать номера строк. -
less-X file1.txt
: По умолчанию при выходе из less содержимое файла будет удалено из командной строки. Если вы хотите выйти, но при этом сохранить содержимое файла на экране, используйте-X
опция.
Синтаксис
меньше [ОПЦИИ] имя файла
Пример
Изображение: Скриншот автора.# Показать содержимое файла $HOME/.pip/pip.conf less $HOME/.pip/pip.conf
11. more Команда
Команду
more
также можно использовать для отображения содержимого файла в командной строке. В отличие отменьше
, эта команда загружает сразу весь файл, поэтомуменьше
кажется быстрее.Некоторые из наиболее полезных опций:
-
more -p file1. txt
: Очистить экран командной строки и затем отобразить содержимоеfile1.txt
-
more +100 file1.txt
: Показать содержимое файлаfile1.txt
, начиная со 100-й строки и далее.
Синтаксис
еще [ВАРИАНТ] имя файла
Пример
Изображение: Скриншот автора.# Показать содержимое файла $HOME/.pip/pip.conf подробнее $HOME/.pip/pip.conf
12. Команда grep
Команда
grep
(глобальное регулярное выражение) полезна, когда вы хотите найти определенную строку в файлах.Вот некоторые из наиболее полезных опций:
-
grep-v Andrew employee.txt
: инвертировать совпадениеAndrew
вemployee.txt
. Другими словами, вывести все строки, не соответствующие шаблону 9.0005 Андрей . -
grep-r Andrew имя_каталога/
: рекурсивный поиск шаблонаAndrew
во всех файлах в указанном каталоге имя_каталога -
grep-i Andrew employees. txt
: поиск без учета регистра.
Синтаксис
grep [ОПЦИИ] ШАБЛОН [ФАЙЛ...]
-
ШАБЛОН
— это шаблон поиска. -
ФАЙЛ
может быть none для большего количества входных имен файлов.
Пример
Поиск команды экспорта в профиле пользователя. Изображение: Скриншот автора.# Поиск `export` (без учета регистра) в профиле пользователя $ grep -i export ~/.bash_profile
13. Команда curl
Команда
curl
используется для загрузки или выгрузки данных с использованием таких протоколов, как FTP, SFTP, HTTP и HTTPS.Синтаксис
curl [ОПЦИИ] [URL...]
Пример
Изображение: Скриншот автора.$ curl -L google.com
14. Команда which
Команда
which
используется для идентификации и сообщения о местонахождении предоставленного исполняемого файла. Например, вы можете захотеть увидеть местоположение исполняемого файла при вызовеpython3
.Синтаксис
which [ОПЦИИ] FILE_NAME
Пример
Изображение: Скриншот автора.$ какой питон3 /usr/local/bin/python3
15. Команда top
Команда
top
может помочь вам контролировать запущенные процессы и ресурсы (например, память), которые они используют в данный момент.Некоторые из наиболее полезных опций:
-
top-u myuser
: Показать процессы для пользователяmyuser
.
Пример
Вывод верхней команды. Изображение: Скриншот автора.16. history Command
Команда
history
отображает историю недавно выполненных команд.Вот некоторые из наиболее полезных параметров:
-
история-5
: отображение последних пяти команд. -
history-c
: Очистить список истории.
-