Что означает запись bin bash в начале исполняемого файла linux

Обновлено: 04.07.2024

Если четвёртый символ это - то файл не является исполняемым.

Сделать его исполняемым можно командой

chmod u+x script_1

-rwxrw-r--. 1 andrei andrei 5252 Nov 26 12:29 script_1

Обратите внимание на -rwx теперь четвёртый символ это x

В моей CentOS настроена подсветка исполняемых файлов, поэтому он теперь зелёный

Теперь выполнить скрипт можно командой

Конкретно этот скрипт должен принимать аргументы из командной строки , поэтому мы выполним

word1 добавится в log.txt а word2 нет, потому что word1 это первый аргумент а word2 второй.

Чтобы записывать вообще все аргументы заменим $1 на $*

Добавим в лог время выполнения команд (подробности здесь)

2020-09-20 17:48:27,404 one two three

Как вызвать скрипт из другого скрипта

Допустим из скрипта parent.sh вам нужно вызвать скрипт child.sh

Это если они в одной директории, если в разных - пишите путь до скрипта

Как назвать скрипт

Проверить не занято ли имя системой можно командой type.

Например, вы решили назвать свой скрипт test

test is a shell builtin

То есть имя занято, вы, конечно, можете его использовать, но с вызовом будут дополнительные сложности.

Вывод команды в переменную

Часто бывает нужно выполнить из скрипта команду и присвоить результат переменной.

Чтобы сделать это воспользуйтесь синтаксисом

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

wc это команда, которая подсчитывает число слов

Аргументы из командной строки

Скрипт может принимать аргументы из командной строки

Первый аргумент обозначается как $1 второй как $2 и так далее

Рассмотрим пример ar.sh

Этот скрипт ждёт один внешний аргумент и присваивает его значение переменной AR

Затем это же значение выводится три раза

В C аналогичную функцию выполняет int argc, char* argv[]

Цикл for

В самом привычном виде цикл for можно записать так

Объединить строки

Конкатенация строк может быть сделана следующим образом

Функции

Чтобы не писать длинные команды вручную можно объединить их в функции.

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

Перезайдите в терминал.

Теперь, чтобы поменять экраны местами достаточно выполнить

Ещё один пример - функция внутри обычного скрипта, она может принимать аргументы, но пока что просто возвращает hi

Какой смысл вставлять? Было бы все иначе?

Это соглашение, поэтому оболочка * nix знает, какой интерпретатор запускать.

Например, в старых версиях ATT по умолчанию использовалась sh (оболочка Bourne), а в более старых версиях BSD по умолчанию использовалась csh (оболочка C).

За ним должен следовать путь к файлу исполняемого файла интерпретатора (который, кстати, может быть даже относительным, но чаще всего абсолютным).

Хороший трюк (или, возможно, не очень хороший), чтобы найти интерпретатор (например, python ) в пользователь $PATH должен использовать программу env (всегда на /usr/bin/env во всех Linux), например,

Стандарты Bash для «оболочки Bourne-Again» - это лишь один из многих типов оболочек, доступных в Linux.

Оболочка - это интерпретатор командной строки, который принимает и запускает команды.

Bash часто является оболочкой по умолчанию в большинстве дистрибутивов Linux. Вот почему bash является синонимом оболочки.

Сценарии оболочки часто имеют почти одинаковый синтаксис, но иногда они различаются. Например, индекс массива начинается с 1 в Zsh вместо 0 в bash. Сценарий, написанный для оболочки Zsh, не будет работать так же в bash, если в нем есть массивы.

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

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

Bash эволюционировал на протяжении многих лет, взяв код из ksh и sh .

Также стоит знать, что shebang - это магическое число - удобочитаемое число, которое идентифицирует файл как скрипт для данного интерпретатора.

Операционная система использует оболочку по умолчанию для запуска вашего сценария оболочки. поэтому, упоминая путь к оболочке в начале скрипта, вы просите ОС использовать эту конкретную оболочку. Это также полезно для переносимости.

Какой смысл вкладывать это в? Будет ли что-то другое?

Это соглашение, поэтому оболочка * nix знает, какой интерпретатор запускать.

Например, более старые версии ATT по умолчанию использовали sh (оболочка Bourne), в то время как более старые версии BSD по умолчанию использовали csh (оболочка C).

Шебанг не является соглашением оболочки , он интерпретируется ядром при обработке execve(2) системного вызова; так что шебанг - это соглашение ядра , а не оболочка. Кроме того, это помогает некоторым редакторам, таким как Vim, определить язык для подсветки синтаксиса, если файл не имеет расширения. Без шебанга Vim будет отображать скрипт bash, такой же, как простой текстовый файл.

За ним должен следовать путь к файлу исполняемого файла интерпретатора (что, кстати, может даже быть относительным, но чаще всего абсолютным).

Хорошая уловка (или, возможно, не очень хорошая ), чтобы найти переводчика (например python ) в пользователе, $PATH состоит в том, чтобы использовать env программу (всегда /usr/bin/env на всех Linux) как, например,

@javascriptninja в любом случае запускает новую оболочку bash. В случае bash на самом деле нет никакой разницы, если вы уже используете bash. Шебанг действительно имеет значение, только если (а) вам нужно запустить что-то, что не является просто оболочкой, например, python или perl, или (б) вы не используете оболочку bash (т.е. вы используете zsh), но вам нужно запустить то, что требует запуска в bash. Тем не менее, по моему мнению, хорошей практикой является включение «шебанга», чтобы кто-нибудь, читающий код, знал, что происходит. Неправильно: execve(2) системный вызов не использует $SHELL переменную. Это ядро ​​интерпретирует Шебанг. @BasileStarynkevitch, что верно, загрузчик эльфов в ядре интерпретирует шебанг. Я заявлял, что $ SHELL будет использоваться, если не будет предоставлен шебанг.

Также стоит знать, что шебанг - это магическое число - читаемое человеком, которое идентифицирует файл как скрипт для данного интерпретатора.

Я сделал Bash скрипты раньше, и все они отлично работали без этого в начале. В чем смысл его вставить? Все будет по-другому?

Это соглашение, так что оболочка * nix знает, какой интерпретатор запускается.

Например, более старые ароматы ATT по умолчанию равны sh (оболочка Bourne), а более старые версии BSD по умолчанию - csh (оболочка C).

Шебанг не является соглашением оболочки , он интерпретируется ядром при обработке execve(2) вызова execve(2) ; так что шебанг - это соглашение ядра , а не оболочка. Кроме того, это помогает некоторым редакторам, таким как Vim, определить язык для подсветки синтаксиса, если файл не имеет расширения. Без шебанга Vim будет отображать скрипт bash, такой же, как простой текстовый файл. ps -u не может вывести имя файла вашего скрипта, если вы не добавите shebang. почему это?

За ним должен следовать путь к файлу исполняемого файла интерпретатора (который BTW может быть даже относительным, но чаще всего является абсолютным).

Хороший трюк (или, возможно, не очень приятный), чтобы найти интерпретатора (например, python ) в пользовательском $PATH - использовать env (всегда на /usr/bin/env на всех Linux), например,

@javascriptninja в любом случае запускает новую оболочку bash. В случае bash на самом деле нет никакой разницы, если вы уже используете bash. Шебанг действительно имеет значение, только если (а) вам нужно запустить что-то, что не является просто оболочкой, например, python или perl, или (б) вы не используете оболочку bash (т.е. вы используете zsh), но вам нужно запустить то, что требует запуска в bash. Тем не менее, по моему мнению, хорошей практикой является включение Шебанга, просто чтобы кто-то, читающий код, знал, что происходит. Неправильно: системный вызов execve(2) не использует переменную $SHELL . Это ядро интерпретирует Шебанг. @BasileStarynkevitch, что верно, загрузчик эльфов в ядре интерпретирует шебанг. Я заявлял, что $ SHELL будет использоваться, если не будет предоставлен шебанг. Я проголосовал за это, потому что это хорошо объясняет, почему я могу запускать bash-скрипты без хеш-бенга. Я запустил echo $SHELL и в результате получил /bin/bash . Так что я чего-то не знал раньше. Благодарю.

Также стоит знать, что shebang - магический номер - читаемый человеком, который идентифицирует файл как script для данного интерпретатора.

Сегодня поговорим о bash-скриптах. Это — сценарии командной строки, написанные для оболочки bash. Существуют и другие оболочки, например — zsh, tcsh, ksh, но мы сосредоточимся на bash. Этот материал предназначен для всех желающих, единственное условие — умение работать в командной строке Linux.




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


Итак, если говорить о командной строке, она позволяет выполнить несколько команд за один раз, введя их через точку с запятой:


На самом деле, если вы опробовали это в своём терминале, ваш первый bash-скрипт, в котором задействованы две команды, уже написан. Работает он так. Сначала команда pwd выводит на экран сведения о текущей рабочей директории, потом команда whoami показывает данные о пользователе, под которым вы вошли в систему.

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


Командная строка — отличный инструмент, но команды в неё приходится вводить каждый раз, когда в них возникает необходимость. Что если записать набор команд в файл и просто вызывать этот файл для их выполнения? Собственно говоря, тот файл, о котором мы говорим, и называется сценарием командной строки.

Как устроены bash-скрипты

Создайте пустой файл с использованием команды touch . В его первой строке нужно указать, какую именно оболочку мы собираемся использовать. Нас интересует bash , поэтому первая строка файла будет такой:


В других строках этого файла символ решётки используется для обозначения комментариев, которые оболочка не обрабатывает. Однако, первая строка — это особый случай, здесь решётка, за которой следует восклицательный знак (эту последовательность называют шебанг) и путь к bash , указывают системе на то, что сценарий создан именно для bash .

Команды оболочки отделяются знаком перевода строки, комментарии выделяют знаком решётки. Вот как это выглядит:


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

Установка разрешений для файла сценария

Сохраните файл, дав ему имя myscript , и работа по созданию bash-скрипта почти закончена. Сейчас осталось лишь сделать этот файл исполняемым, иначе, попытавшись его запустить, вы столкнётесь с ошибкой Permission denied .


Попытка запуска файла сценария с неправильно настроенными разрешениями

Сделаем файл исполняемым:


Теперь попытаемся его выполнить:


После настройки разрешений всё работает как надо.


Успешный запуск bash-скрипта

Для вывода текста в консоль Linux применяется команда echo . Воспользуемся знанием этого факта и отредактируем наш скрипт, добавив пояснения к данным, которые выводят уже имеющиеся в нём команды:


Вот что получится после запуска обновлённого скрипта.


Теперь мы можем выводить поясняющие надписи, используя команду echo . Если вы не знаете, как отредактировать файл, пользуясь средствами Linux, или раньше не встречались с командой echo , взгляните на этот материал.

Использование переменных

Переменные позволяют хранить в файле сценария информацию, например — результаты работы команд для использования их другими командами.

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

Существуют два типа переменных, которые можно использовать в bash-скриптах:

  • Переменные среды
  • Пользовательские переменные

Переменные среды

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


Обратите внимание на то, что мы можем использовать системную переменную $HOME в двойных кавычках, это не помешает системе её распознать. Вот что получится, если выполнить вышеприведённый сценарий.


Использование переменной среды в сценарии

А что если надо вывести на экран значок доллара? Попробуем так:


Система обнаружит знак доллара в строке, ограниченной кавычками, и решит, что мы сослались на переменную. Скрипт попытается вывести на экран значение неопределённой переменной $1 . Это не то, что нам нужно. Что делать?

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


Теперь сценарий выведет именно то, что ожидается.


Использование управляющей последовательности для вывода знака доллара

Пользовательские переменные

В дополнение к переменным среды, bash-скрипты позволяют задавать и использовать в сценарии собственные переменные. Подобные переменные хранят значение до тех пор, пока не завершится выполнение сценария.

Как и в случае с системными переменными, к пользовательским переменным можно обращаться, используя знак доллара:

Вот что получится после запуска такого сценария.


Пользовательские переменные в сценарии

Подстановка команд

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

Сделать это можно двумя способами.

  • С помощью значка обратного апострофа «`»
  • С помощью конструкции $()


При втором подходе то же самое записывают так:


А скрипт, в итоге, может выглядеть так:


В ходе его работы вывод команды pwd будет сохранён в переменной mydir , содержимое которой, с помощью команды echo , попадёт в консоль.


Скрипт, сохраняющий результаты работы команды в переменной

Математические операции

Для выполнения математических операций в файле скрипта можно использовать конструкцию вида $((a+b)) :


Математические операции в сценарии

Управляющая конструкция if-then

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


А вот рабочий пример:


В данном случае, если выполнение команды pwd завершится успешно, в консоль будет выведен текст «it works».

Воспользуемся имеющимися у нас знаниями и напишем более сложный сценарий. Скажем, надо найти некоего пользователя в /etc/passwd , и если найти его удалось, сообщить о том, что он существует.


Вот что получается после запуска этого скрипта.


Поиск пользователя

Здесь мы воспользовались командой grep для поиска пользователя в файле /etc/passwd . Если команда grep вам незнакома, её описание можно найти здесь.

Управляющая конструкция if-then-else

Для того, чтобы программа смогла сообщить и о результатах успешного поиска, и о неудаче, воспользуемся конструкцией if-then-else . Вот как она устроена:


Если первая команда возвратит ноль, что означает её успешное выполнение, условие окажется истинным и выполнение не пойдёт по ветке else . В противном случае, если будет возвращено что-то, отличающееся от нуля, что будет означать неудачу, или ложный результат, будут выполнены команды, расположенные после else .

Напишем такой скрипт:


Его исполнение пошло по ветке else .


Запуск скрипта с конструкцией if-then-else


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


В подобном скрипте можно, например, создавать нового пользователя с помощью команды 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 .

В качестве примера опробуем один из операторов сравнения. Обратите внимание на то, что выражение заключено в квадратные скобки.


Вот что выведет эта команда.


Сравнение чисел в скриптах

Сравнение строк

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

str1 = str2 Проверяет строки на равенство, возвращает истину, если строки идентичны.
s tr1 != str2 Возвращает истину, если строки не идентичны.
str1 < str2 Возвращает истину, если str1 меньше, чем str2 .
str1 > str2 Возвращает истину, если str1 больше, чем str2 .
-n str1 Возвращает истину, если длина str1 больше нуля.
-z str1 Возвращает истину, если длина str1 равна нулю.

Вот пример сравнения строк в сценарии:


В результате выполнения скрипта получим следующее.


Сравнение строк в скриптах

Вот как работа с этими операторами выглядит в коде:


Вот результаты работы скрипта.


Сравнение строк, выведенное предупреждение

Обратите внимание на то, что скрипт, хотя и выполняется, выдаёт предупреждение:


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


Теперь всё работает как надо.


Сравнение строк

Ещё одна особенность операторов «>» и «<» заключается в том, как они работают с символами в верхнем и нижнем регистрах. Для того, чтобы понять эту особенность, подготовим текстовый файл с таким содержимым:


Сохраним его, дав имя myfile , после чего выполним в терминале такую команду:


Она отсортирует строки из файла так:


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


Если его запустить, окажется, что всё наоборот — строчная буква теперь больше прописной.


Команда 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 Проверяет, существует ли файл, и соответствует ли его идентификатор группы идентификатору группы текущего пользователя.

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

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


Этот скрипт, для существующей директории, выведет её содержимое.


Вывод содержимого директории

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

Итоги

Сегодня мы рассказали о том, как приступить к написанию bash-скриптов и рассмотрели некоторые базовые вещи. На самом деле, тема bash-программирования огромна. Эта статья является переводом первой части большой серии из 11 материалов. Если вы хотите продолжения прямо сейчас — вот список оригиналов этих материалов. Для удобства сюда включён и тот, перевод которого вы только что прочли.

    — здесь речь идёт о том, как начать создание bash-скриптов, рассмотрено использование переменных, описаны условные конструкции, вычисления, сравнения чисел, строк, выяснение сведений о файлах.

— тут раскрываются особенности работы с циклами for и while.

— этот материал посвящён параметрам командной строки и ключам, которые можно передавать скриптам, работе с данными, которые вводит пользователь, и которые можно читать из файлов.

— здесь речь идёт о дескрипторах файлов и о работе с ними, о потоках ввода, вывода, ошибок, о перенаправлении вывода.

— этот материал посвящён сигналам Linux, их обработке в скриптах, запуску сценариев по расписанию.

— тут можно узнать о создании и использовании функций в скриптах, о разработке библиотек.

— эта статья посвящена работе с потоковым текстовым редактором sed.

— данный материал посвящён программированию на языке обработки данных awk.

— тут можно почитать об использовании регулярных выражений в bash-скриптах.

Читайте также: