Сколько способов исполнить скрипт bash?

Когда мы вызываем скрипт из терминала — то этот скрипт становится отдельным процессом, дочерним от процесса терминала. Он наследует все переменные среды, которые были объявлены через export $VAR (а не просто $VAR — простые не будут видны.) Когда этот дочерний скрипт изменяет унаследованную переменную — эта переменная уже его лично, в родительском процессе значение переменной не меняется. Надёжный способ передать из дочернего процесса в родительский какую-то инфу — это возвратить какие-то результаты, как из функции, или послать вывод дочерней функции в пайп.
bash ввёл такую тему: «встраивание» кода, прочитанного из другого файла прямо в текущий процесс. Файл не обязан быть исполняемым, а по правилам хорошего тона — его таким и не делают.
Примеры таких команд:
Это позволяет исполнить посторонний код, он обновляет переменные, а текущий процесс этим пользуется. Если бы посторонний код был запущен как дочерний — это не получилось бы. Если подключаемы скрипт захочет навредить — он навредит. Если в нём exit — то весь процесс закроется, не отработав до конца.
В подключаемом скрипте могут быть только переменные и функции — тогда переменные запишутся в текущее окружение, а функции будут доступны для вызова. Если и в текущем и в новом скрипте есть функции с одинаковым именем — нужно сперва текущую переназвать declare -f new_function_name=old_function_name , а потом делать вставку source side_bashcode .
Говорят, что ради возможности загрузить переменные из посторонних источников это и сделали. Ради того, чтоб у каждого пользователя был свой личный .profile (вызывается при логине) и .bashrc (вызывается при создании терминала). Это не синонимы. Окошко с терминалом можно закрыть, или открыть второе — .bashrc прочтётся заново. Даже без GUI — команда exec $SHELL делает то же самое, заставляет заменить текущий процесс командной оболочки на новый процесс, возможно даже на другое приложение. Оно запустится с нуля, как будто после логина. Но без самого логина, без перезагрузки .profile . Зато перезагрузится .bashrc.
Оригинальный, более старый и «совместимый со всеми» shell (sh), похоже, такого не умеет.
Запуск дочернего процесса
Это «обычный» запуск. Когда запускаем скрипт по имени, или приложение — то «родительская» (та, из которой исходит команда) прилога создаёт копию своего процесса, грузит в процесс код из запускаемого приложения, и «передаёт управление» = прекращает посылать команды, начинает с команды новой прилоги, которая описана как «точка входа». Примеры:
Чтобы вызвать так, нужно поставить разрешение «execute». Если это не машкод, а текст — в нём указать первой строкой #!/path/to/interpreter. Если хочешь вызывать его из любого каталога — добавь его в одну из папок $PATH, или папку с ним добавь в $PATH. Вуаля, системная команда, как у взрослых!
Дочка может унаследовать права от матери. Если найдёт себе материнский процесс, работающий под именем root, и тот позволит отпочковаться с теми же правами — вау, у процесса права на всё!
Какие ещё способы запуска?
#!/bin/bash SCRIPT_PATH="/path/to/script.sh" # Insert . "$SCRIPT_PATH" # Insert source "$SCRIPT_PATH" # Fork "$SCRIPT_PATH" # Fork bash "$SCRIPT_PATH" # ? eval '"$SCRIPT_PATH"' # ? OUTPUT=$("$SCRIPT_PATH") echo $OUTPUT # ? OUTPUT=`"$SCRIPT_PATH"` echo $OUTPUT # обратные кавычки тоже запускают скрипт! ./script-that-consumes-argument.sh `sh script-that-produces-argument.sh` # ? ("$SCRIPT_PATH") # ? (exec "$SCRIPT_PATH")
Вариант с двумя файлами:
& в конце — он позволит форкнуть процесс и тут же отключить его от терминала. Процесс работает сам по себе, а мы его не ждём, можем вводить новые команды или запускать параллельные процессы.
Внимейшн! Я узнал три варианта echo :
- echo в sh — команда, которая не понимает опции -e (она её просто печатает как будто это целевой текст), но зато понимает, что \n (и другие эскейпы) нужно превращать в спецсимволы;
- echo в bash — команда, которая без опции -e не превращает \n и другие эскейпы, ей нужно прямо заказать опцию -e — и тогда начнёт превращать;
- echo в GNU utilites — вообще самостоятельная прилога, у неё тоже какие-то особенности.
В общем, советы в интернете противоречат друг другу, проще прочитать man echo о том варианте, который используете вы.
Записать переменную в файл
"$destfile" fi
"$destfile"
printf работает как в C:
"$destfile"
Эти ответы не сработают, если текст:
- начинается с -e, или с -n, или с -E
- или содержит \n
- не должен заканчиваться переводом строки, когда будет записан в файл.
Что тогда поможет?
"$destfile" printenv var > "$destfile"
printenv [name] — print out the environment [or just only name value if specified] env [-] [-i] [name=value . ] [utility [argument . ]] — set and print environment
Я видел одно упоминание этой команды, а команда есть!
Как запустить Bash скрипт в Linux
![]()
Как системный администратор, вполне вероятно, что вы написали несколько сценариев Bash для автоматизации вашей работы. Например, вы можете запускать сценарии Bash для резервного копирования вашей работы или для регистрации некоторых событий, происходящих на вашем сервере.
Скрипты Bash, как и скрипты, написанные на других языках программирования, могут запускаться различными способами.
В этой статье мы расскажем о всех способах запуска скрипта Bash в Linux.
Подготовка
Прежде чем вы сможете запустить ваш скрипт, вам нужно, чтобы ваш скрипт был исполняемым. Чтобы сделать исполняемый скрипт в Linux, используйте команду chmod и присвойте файлу права execute . Вы можете использовать двоичную или символическую запись, чтобы сделать ее исполняемой.
$ chmod u+x script $ chmod 744 script
Если вы не являетесь владельцем файла, вам необходимо убедиться, что вы принадлежите к правильной группе или что права доступа предоставлены «другой» группе в вашей системе.
В некоторых дистрибутивах ваш файл будет выделен другим цветом, когда он исполняемый.
Теперь, когда ваш файл исполняемый, давайте посмотрим, как можно легко запустить скрипт Bash.
Запустить Bash скрипт из пути к скрипту
Чтобы запустить Bash скрипт в Linux, просто укажите полный путь к скрипту и укажите аргументы, которые могут потребоваться для запуска Bash скрипта.
$ /path/to/script .
В качестве примера, скажем, у вас есть Bash-скрипт, расположенный в вашем домашнем каталоге.
Чтобы выполнить этот скрипт, вы можете указать полный путь к скрипту, который вы хотите запустить.
# Абсолютный путь $ /home/user/script # Абсолютный путь с аргументами $ /home/user/script "john" "jack" "jim"
Кроме того, вы можете указать относительный путь к скрипту Bash, который вы хотите запустить.
# Относительный путь $ ./script # Относительный путь с аргументами $ ./script "john" "jack" "jim"
Таким образом вы узнали, как легко запустить Bash-скрипт в своей системе.
Запустить Bash скрипт, используя bash
Чтобы запустить скрипт Bash в вашей системе, вы должны использовать команду bash и указать имя скрипта, который вы хотите выполнить, с необязательными аргументами.
$ bash
Кроме того, вы можете использовать sh , если в вашем дистрибутиве установлена утилита sh .
В качестве примера, скажем, вы хотите запустить скрипт Bash с именем script . Чтобы выполнить его с помощью утилиты bash , вы должны выполнить следующую команду
$ bash script This is the output from your script!
Выполнить скрипт Bash, используя sh, zsh, dash
В зависимости от вашего дистрибутива, в вашей системе могут быть установлены другие утилиты оболочки.
Bash — интерпретатор оболочки, установленный по умолчанию, но вы можете захотеть выполнить ваш скрипт с использованием других интерпретаторов. Чтобы проверить, установлен ли интерпретатор оболочки в вашей системе, используйте команду which и укажите нужный интерпретатор.
$ which sh /usr/bin/sh $ which dash /usr/bin/dash
Когда вы определили интерпретатор оболочки, который хотите использовать, просто вызовите его, чтобы легко запустить скрипт.
Запуск скрипта Bash из любого места
В некоторых случаях вы можете запускать скрипты Bash, где бы вы ни находились в вашей системе.
Чтобы запустить скрипт Bash из любой точки вашей системы, вам нужно добавить свой скрипт в переменную среды PATH .
$ export PATH=":$PATH"
Благодаря тому, что путь к скрипту добавлен в PATH , вы можете вызывать его там, где хотите в своей системе.
$ script This is the output from script!
Кроме того, вы можете изменить переменную среды PATH в вашем файле .bashrc и использовать команду source для обновления вашей текущей среды Bash.
$ sudo nano ~/.bashrc export PATH=":$PATH"
Выйдите из файла и используйте команду source для файла bashrc для внесения изменений.
$ source ~/.bashrc $ echo $PATH /home/user/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Отлично! Теперь ваш скрипт может быть запущен из любой точки вашей системы.
Запуск Bash скриптов из графического интерфейса
Последний способ выполнения Bash скриптов — это использование графического интерфейса, в данном случае интерфейса GNOME.
Чтобы запустить ваши скрипты с использованием GNOME, вы должны установить в проводнике Ask what to do для исполняемых файлов.
Закройте это окно и дважды щелкните файл скрипта, который вы хотите выполнить.
При двойном щелчке вам предлагаются различные варианты: вы можете выбрать запуск скрипта (в терминале или нет) или просто отобразить содержимое файла.
В этом случае мы заинтересованы в запуске этого скрипта в терминале, поэтому нажмите на эту опцию.
Успех! Ваш скрипт был успешно выполнен
Заключение
Из этого руководства вы узнали, как легко запускать Bash скрипты в своей системе, указав путь к скрипту или интерпретаторы, доступные на вашем хосте. Вы узнали, что можете сделать это еще проще, добавив путь к скрипту в переменную среды PATH или используя существующие функции в пользовательском интерфейсе GNOME.
Как выполнить bash скрипт
Выполнить bash скрипт в консоли можно обратившись к нему по полному пути из корня сервера или из текущего каталога указав путь от него. Если файл с инструкциями размещается в домашнем каталоге пользователя root запустить его можно выполнив /root/script
Условием выполнения является установленный в качестве интерпретатора /bin/bash для пользователя. В большинстве систем это так.
Проверить оболочку можно просмотрев файл /etc/passwd
cat /etc/passwd| grep root
root:x:0:0:root:/root:/bin/bash
В примере выше видно что для пользователя root установлена оболочка /bin/bash.
Как выполнить bash скрипт в Linux
Если там что-то другое, то bash скрипт можно вызвать указывая интерпретатор непосредственно
/bin/bash /root/script
Выполнить bash скрипт можно из произвольной точки в файловой системе указав
Точка означает текущую директорию, после слэша следует имя скрипта.
Бит исполнения при выполнении bash скриптов
Файл должен быть исполняемым если для него не указывается интерпретатор и используется только полный путь.
Сделать файл исполняемым можно используя chmod
bash скрипт подразумевает указание в первой строке символа she-bang и интерпретатора bash. Также могут задаваться и другие интерпретаторы
#!/bin/bash
..
..
Без использования этих символов скрипт также будет выполняться если в нем прописаны простейшие команды, но при сложных инструкциях он может не отрабатывать или отрабатывать некорректно поэтому интерпретатор всегда стоит указывать.
Чтобы убедиться в том, что скрипт выполняется можно поместить в него инструкцию типа echo ‘hello world’.

Готовые bash скрипты часто используются в CRON заданиях.
На bash можно написать простое консольное меню или скрипт создания бэкапов, или например скрипт, меняющий тип таблиц баз данных.
27. bash скрипты №1
Изучать что-то новое может быть интересно — новые знания, новый опыт. Вот мы изучили рейд, лвм, файловые системы и всё такое, попрактиковались пару раз – всё довольно просто. Но вы устраиваетесь на работу, там есть какая-то инфраструктура и ваша задача – администрировать эту инфрастуктуру. И то что вчера было новым и интересным превращается в рутину – вам постоянно нужно работать с одними и теми же командами, изо дня в день, годами. Где-то пользователей создать и права настроить, где-то бэкап сделать, где-то ещё что. И люди ищут способы, как бы это всё автоматизировать. Автоматизировать графический интерфейс довольно сложно. Писать новую программу ради какой-то рутины не всегда стоит того. И тут текстовый интерфейс раскрывает себя во всей красе. Можно написать так называемые сценарии, какие команды и как будут выполняться. И запускать этот сценарий вручную, либо автоматизировать его запуск, что вообще позволит админу избавиться от рутины.
Мы работаем с bash, поэтому будем учиться писать сценарии для него. Более привычное название – скрипты. Кто-то называет это «bash программированием». И давайте сразу поставим себе задачу, которую будем решать с помощью скрипта. Начнём с чего-то простого – создать двух пользователей:
- Основная группа — it
- it – группа с правами суперпользователя
- Домашняя директория в /home/it
- Оболочка — /bin/bash
- Основная группа — users
- Домашняя директория в /home/users
- Оболочка — /sbin/nologin
Один из них — user1 — его основная группа будет it, у которой будут права суперпользователя, его домашняя директория будет внутри директории /home/it и его оболочка будет bash. Второй пользователь – user2 — будет в группе users, домашняя директория внутри директории /home/users, а оболочка nologin. Кстати, попробуйте самостоятельно вспомнить все команды, которые необходимо выполнить.

Для начала вспомним, как это делается. Во первых, нужно создать группы и директории. Создаём группу it:
sudo groupadd it
Группа users есть по умолчанию:
grep users /etc/group
У группы it должны быть права суперпользователя – заходим в:
visudo
и добавляем строчку:
%it ALL=(ALL) ALL
Дальше нам нужны директории — /home/it и /home/users:
sudo mkdir -v /home/it,users>
И наконец создаём пользователей:
sudo useradd user1 -g it -b /home/it -s /bin/bash sudo useradd user2 -g users -b /home/users -s /sbin/nologin tail /etc/passwd
Всего у нас получилось 5 команд:
sudo groupadd it sudo visudo sudo mkdir -v /home/it,users> sudo useradd user1 -g it -b /home/it -s /bin/bash sudo useradd user2 -g users -b /home/users -s /sbin/nologin

Теперь давайте сделаем скрипт – просто вставим все эти 5 команд в файл с любым названием:
nano myscript
Каждая команда с новой строки.

Но прежде чем запускать скрипт, надо вернуть всё как было – удаляем пользователей, группу, директории и запись из sudoers:
sudo userdel -r user1 sudo userdel -r user2 sudo groupdel it sudo rm -r /home/ sudo visudo sudo grep «%it» /etc/sudoers

Запускаем скрипт с помощью bash:
bash myscript
У меня открылся visudo – это один из шагов, когда мне нужно добавить группу it в sudoers. Добавил, сохранил. Теперь опять проверяем:
tail /etc/passwd
всё создалось. И это одной командной, не считая ручного заполнения visudo.

Но.. мы говорим про автоматизацию, а мне всё равно приходится добавлять запись в sudoers вручную. Давайте сделаем так, чтобы запись добавлялась без нашего участия. Помните, как мы делали с рейдом – писали echo текст и направляли в файл? Сделаем точно также. Заменим в нашем файле visudo на echo:
nano myscript
echo %it ALL=(ALL) ALL
Возьмём текст в одинарные кавычки, чтоб баш никак не обработал команду и направим этот текст в файл /etc/sudoers:
echo '%it ALL=(ALL) ALL' >> /etc/sudoers
с помощью двух символов больше, чтобы не перезаписать файл, а дополнить. Правда сама такая команда не сработает – перенаправление вывода (>>) выполняется от моей оболочки, не от команды sudo, а у моего пользователя не хватит прав записать что-то в sudoers.
sudo echo '%it ALL=(ALL) ALL' >> /etc/sudoers

Можно, конечно, использовать команду tee, но, вообще, учитывая, что все команды тут выполняются с sudo, легче сделать по другому. Просто сотрём отсюда все sudo, а при запуске, вместо bash myscript будем писать:
sudo bash myscript
Тогда весь скрипт будет выполняться в оболочку суперпользователя – это и избавит нас от проблемы с перенаправлением вывода и не будет необходимости внутри скрипта запускать sudo.

Но неплохо было бы на всякий случай сделать копию файла sudoers, чтобы случайно его не испортить. Добавим команду в начале скрипта:
nano myscript
Хорошо, теперь опять удалим то что создали:
sudo userdel -r user1 sudo userdel -r user2 sudo groupdel it sudo rm -r /home/it,users> sudo visudo cp /etc/sudoers.bkp>

И заново запустим скрипт:
sudo bash myscript tail -2 /etc/passwd sudo tail -1 /etc/sudoers
Сработало – одной командой мы создали всё что нам нужно.

Чтобы наш скрипт выглядел более самостоятельным, то есть, чтобы нам не приходилось каждый раз перед ним писать bash, а также чтобы мы могли делиться этим скриптом с другими, кто, возможно, использует другие оболочки, мы можем внутри самого скрипта указать, а под какой именно интерпретатор написан скрипт. Так как, теоретически, у нас в скрипте могут быть всякие особенности, присущие только bash, которых нет в других интерпретаторах. Но тут могут быть нюансы – нужно понимать, что bash есть во многих системах, но не во всех. Если вы пишете скрипт, который предполагаете использовать не только на GNU/Linux, но и на всяких UNIX-ах, где может не быть bash-а, то лучше писать скрипты под интерпретатор shell. Чтобы указать, с помощью какого интерпретатора запускать скрипт, в первой строчке самого скрипта указываются два символа:
называемые шебанг, после чего указывается путь к интерпретатору, допустим:
#!/bin/bash

Но так как в разных дистрибутивах и системах bash или другой интерпретатор могут находится в разных директориях, есть более универсальный способ написания пути:
#!/usr/bin/env bash
Давайте так и оставим. Правда, так как теперь мы будем запускать скрипт напрямую, а не передавая его программе bash, ему понадобятся права для запуска – для этого пишем:
chmod +x myscript
sudo myscript
не получится – sudo будет искать программу myscript в директориях её переменной PATH. Либо нужно поместить myscript в одну из директорий переменной PATH, либо явно указывать путь к этому скрипту – достаточно поставить перед ним точку и слеш, если он в текущей директории:
sudo ./myscript

Но наш скрипт получился слишком однозадачным – он нацелен на создание двух конкретных пользователей. Сойдёт на разок, но потом, если понадобится создать ещё пользователей, придётся изменять скрипт. Давайте сделаем наш скрипт более динамическим – добавим в него переменные. Пользователей и группы заменим на переменные – user1,user2,group1,group2, а так как директории совпадают с именами групп, там тоже используем переменные. В строке echo одинарные кавычки, а значит переменная не обработается. Надо немного переделать строчку. Можно по разному, но я просто оставлю переменную group1 за кавычками. Теперь, если мне понадобится выполнить скрипт для других пользователей и групп, я могу просто заменить в начале скрипта значения переменных, вместо того, чтобы переделывать весь скрипт.

Опять же получилось так себе – у нас тут скрипт на двух пользователей в двух группах – а если мне нужно добавить одного или трёх пользователей? Давайте уберём всё что касается user2 и group2. Конечно, для второго пользователя придётся опять запускать скрипт, но динамичность скрипта это компенсирует.
Хотя.. в скрипте всё ещё вручную прописаны переменные user и group. Придётся для каждого пользователя заходить и менять значения. Обычно, когда мы работаем с программами в командной строке, мы передаём ей какие-то параметры. Нельзя ли пользователя и группу передать в виде параметров, чтоб не приходилось менять скрипт? Можно.

Давайте сделаем так – создадим новый скрипт:
nano test
сохраним и дадим права: