Домой / Mozilla Firefox / Запуск PHP скрипта по расписанию cron. Когда не всё так ясно. Написание скриптов на Bash

Запуск PHP скрипта по расписанию cron. Когда не всё так ясно. Написание скриптов на Bash

В этой статье расскажу про запуск Shell скриптов (*.sh) на Ubuntu.

Файл *.sh это скрипт, сценарий в системе Linux .
При запуске его выполняются поочередно команды записанные в него.

На самом деле это просто текстовый файл с инструкциями для системы Linux, которые выполняются поочередно.

Давайте напишем простой.sh скрипт, который запустим в нашей системе.

Создайте текстовый файл в вашей домашней директории, откройте его и напишите в него следующие строчки:

Shell

#!/bin/bash echo "Hello World"

#!/bin/bash

echo "Hello World"

Сохраните его, как hello.sh
У вас получится вот такой текстовый файл в домашнем каталоге:

Вот мы и создали sh скрипт .

Как запустить sh скрипт из командной строки?

Для этого нужно:
1. Перейти в каталог нахождения скрипта, с помощью консольной команды cd . Так как мы сохранили этот скрипт в домашней директории, то переходить в какой либо каталог не нужно.

2. Сделать наш файл исполняемым.
Для этого введите команду chmod +x и имя файла скрипта:

chmod +x hello.sh

3. Теперь запускаем его:

Также можно запустить следующей командой:

Если всё правильно сделали, то в консоле выведется "Hello world" :


Как запустить sh в графическом интерфейсе (GUI)?

1. Переходим в каталог с нашим sh скриптом:

На вкладке "Поведение" в пункте "Исполняемые текстовые файлы " должно быть выбрано или "Каждый раз спрашивать" или "Запускать исполняемые текстовый файлы при открытии".
Разница у них в том, что если выбрать "Каждый раз спрашивать", то у вас будет выбор: запустить скрипт в консоле или в графическом интерфейсе. Во втором случае запуск будет только в графическом режиме.

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

Но если Вы хотите создать ярлык для sh скрипта в системе Ubuntu, то прочтите следующую мою статью.

Для создания и выполнения скрипта в области скриптов выполните описанные действия.

В области скриптов можно открывать и редактировать тип файла. В данный момент нас интересуют следующие типы файлов Windows PowerShell: файлы скриптов (PS1), файлы данных скриптов (PSD1) и файлы модулей скриптов (PSM1). Эти типы файлов имеют цветовую подсветку синтаксиса в редакторе области скриптов. Другие стандартные файлы, которые можно открыть в области скриптов, - это файлы конфигурации (PS1XML), файлы XML и текстовые файлы.

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

Нажмите кнопку Создать Файл и выберите пункт Создать . Созданный файл появится в новой вкладке. По умолчанию создается файл типа скрипт (PS1), но его можно сохранить с новым именем и расширением. На одной вкладке PowerShell может быть создано несколько файлов скриптов.

Открытие существующего скрипта

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

Отображение пути к файлу

Запуск скрипта

Нажмите кнопку Выполнить скрипт на панели инструментов или откройте меню Файл и выберите Выполнить .

Запуск части скрипта

  1. В области скриптов выделите часть скрипта.
  2. В меню Файл выберите или на панели инструментов нажмите кнопку Выполнить выделенный фрагмент .

    Остановка выполняемого скрипта

    Нажмите на панели инструментов кнопку Остановить выполнение , нажмите клавиши CTRL+BREAK или в меню Файл выберите пункт Остановить выполнение . Нажатие клавиш CTRL+C также сработает, если нет выделенного текста, в противном случае функция копирования сработает для выделенного текста.

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

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

Основы скриптов

Скрипт или как его еще называют — сценарий, это последовательность команд, которые по очереди считывает и выполняет программа-интерпретатор, в нашем случае это программа командной строки — bash.

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

Простейший пример скрипта для командной оболочки Bash:

!/bin/bash
echo "Hello world"


Утилита echo выводит строку, переданную ей в параметре на экран. Первая строка особая, она задает программу, которая будет выполнять команды. Вообще говоря, мы можем создать скрипт на любом другом языке программирования и указать нужный интерпретатор, например, на python:

!/usr/bin/env python
print("Hello world")

Или на PHP:

!/usr/bin/env php
echo "Hello world";

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

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

Чтобы выполните:

chmod ugo+x файл_скрипта

Теперь выполняем нашу небольшую первую программу:

./файл_скрипта


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

Переменные в скриптах

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

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

Например, объявим переменную string:

string="Hello world"

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

Чтобы вывести значение переменной используется символ $. Например:

Модифицируем наш скрипт:

!/bin/bash
string1="hello "
string2=world
string=$string1$string2
echo $string

И проверяем:

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

!/bin/bash
string1="hello "
string2=world
string=$string1$string2\ and\ me
string3=$string1$string2" and me"
echo $string3


Проверяем:

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

Переменные и вывод команд

Переменные не были бы настолько полезны, если бы в них невозможно было записать результат выполнения утилит. Для этого используется такой синтаксис:

$(команда )

С помощью этой конструкции вывод команды будет перенаправлен прямо туда, откуда она была вызвана, а не на экран. Например, утилита date возвращает текущую дату. Эти команды эквивалентны:


Понимаете? Напишем скрипт, где будет выводиться hello world и дата:

string1="hello world "
string2=$(date)

string=$string1$string2


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

Параметры скрипта

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

Переменная с именем 1 содержит значение первого параметра, переменная 2, второго и так далее. Этот bash скрипт выведет значение первого параметра:

!/bin/bash
echo $1



Управляющие конструкции в скриптах

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

В Bash для проверки условий есть команда Синтаксис ее такой:

if команда_условие
then
команда
else
команда
fi

Эта команда проверяет код завершения команды условия, и если 0 (успех) то выполняет команду или несколько команд после слова then, если код завершения 1 выполняется блок else, fi означает завершение блока команд.

Но поскольку нам чаще всего нас интересует не код возврата команды, а сравнение строк и чисел, то была введена команда [[, которая позволяет выполнять различные сравнения и выдавать код возврата зависящий от результата сравнения. Ее синтаксис:

[[ параметр1 оператор параметр2 ]]

Для сравнения используются уже привычные нам операторы <,>,=,!= и т д. Если выражение верно, команда вернет 0, если нет — 1. Вы можете немного протестировать ее поведение в терминале. Код возврата последней команды хранится в переменной $?:


Теперь объединением все это и получим скрипт с условным выражением:

!/bin/bash
if [[ $1 > 2 ]]
then
echo $1" больше 2"
else
echo $1" меньше 2 или 2"
fi



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

Циклы в скриптах

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

Первым рассмотрим цикл for. Вот его синтаксис:

for переменная in список
do
команда
done

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

Например, переберем пять цифр:

for index in 1 2 3 4 5
do
echo $index
done



Или вы можете перечислить все файлы из текущей директории:

for file in $(ls -l); do echo "$file"; done


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

Второй цикл, который мы рассмотрим — это цикл while, он выполняется пока команда условия возвращает код 0, успех. Рассмотрим синтаксис:

while команда условие
do
команда
done

Рассмотрим пример:

!/bin/bash
index=1
while [[ $index < 5 ]]
do
echo $index
let "index=index+1"
done



Как видите, все выполняется, команда let просто выполняет указанную математическую операцию, в нашем случае увеличивает значение переменной на единицу.

Хотелось бы отметить еще кое-что. Такие конструкции, как while, for, if рассчитаны на запись в несколько строк, и если вы попытаетесь их записать в одну строку, то получите ошибку. Но тем не менее это возможно, для этого там, где должен быть перевод строки ставьте точку с комой «;». Например, предыдущий цикл можно было выполнить в виде одной строки:

index=1; while [[ $index < 5 ]]; do echo $index; let "index=index+1"; done;

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

Выводы

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

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

В простейшем случае, скрипт можно создать, например, так:

$ echo "ls | grep script" > script

ls | grep script

Здесь мы создали текстовый файл, содержащий команды ls и grep, и далее выполнили эти команды, вызвав интерпретатор команд и передав ему в качестве аргумента имя скрипта. Интерпретатор команд, получив в качестве аргумента имя файла, считал из него команды и выполнил их.

Такой способ запуска скриптов не очень удобен. Он отличается от вызова команд системы: здесь требуется в командной строке указывать имя интерпретатора команд и, в общем случае, полный путь к выполняемому скрипту, в то время как для скомпилированных команд системы достаточно ввести имя самой команды. Кроме того, для операционных систем *nix существует несколько альтернативных командных интерпретаторов с различным синтаксисом команд. Существует и большое количество различных интерпретирующих языков программирования, программы для которых также оформляются в виде скриптов и запускаются с помощью соответствующих программ-интерпретаторов. Таким образом, требуется способ указать системе, каким именно интерпретатором следует выполнять тот или иной скрипт.

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

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

Как рассматривалось в предыдущей лабораторной работе,
в операционных системах *nix существуют права доступа к файлам. Если для файла задано право его выполнения, то интерпретатор команд откроет его и прочитает несколько первых символов файла. Если там обнаружится начало скомпилированной программы, то она будет запущена, если же там обнаружится последовательность символов #!, то будет запущен указанный после неё интерпретатор, которому будет передано в качестве аргумента имя файла.

$ echo "#!/bin/bash" > script

$ echo "ls | grep script" >> script

$ chmod a+x script

ls | grep script

Rwxr-xr-x 1 student student 29 Мар 20 09:35 script

Здесь мы создали путём вызова двух команд echo файл (обратите внимание, что во второй команде мы дописали строку в имеющий файл), задали этому файлу право на выполнение, проверили результат (выведя файл через cat и проверив права на него через ls -l) и запустили его на выполнение.

Отметим, что командный интерпретатор ищет выполняемые файлы в определённых местах: /bin, /usr/bin и т.п. Для запуска программы из нестандартного места требуется указывать путь к ней, т.е., в данном случае, запустить программу как script нельзя - вместо созданного нами скрипта командный интерпретатор запустит стандартную утилиту script из /usr/bin.

Часто простого последовательного выполнения недостаточно - для эффективного программирования требуются переменные, условное выполнение команд и т.п. Командный интерпретатор имеет собственный язык, который по своим возможностям приближается к высокоуровневым языкам программирования. Этот язык позволяет создавать программы (shell -файлы, скрипты), которые могут включать операторы языка и команды UNIX.

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

Скрипту могут быть переданы аргументы при запуске. Каждому из первых девяти аргументов ставится в соответствие позиционный параметр от $1 до $9 ($0 - имя самого скрипта), и по этим именам к ним можно обращаться из текста скрипта.

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

● \ (обратный слеш) - знак отмены специального символа перевода строки, следующего непосредственно вслед за этим знаком.

● "" (апострофы) - используются для обрамления текста, передаваемого как единый аргумент команды.

● "" (двойные кавычки) - используются для обрамления текста, содержащего имена переменных для подстановки ($имя) или стандартные команды, заключенные в символы обратного апострофа (`команда`).

● `` (обратные апострофы) - служат для выполнения команды, заключенной между ними.

Кроме того, для удобства работы с файлами почти все командные интерпретаторы интерпретируют символы? (знак вопроса) и * (астериск), используя их как шаблоны имен файлов (т.н. метасимволы):

● ? - один любой символ;

● * - произвольное количество любых символов.

Например, *.c обозначает все файлы с расширением c,
pr???.* обозначает файлы, имена которых начинаются с pr, содержат пять символов и имеют любое расширение.

Если на вопрос: «как добавить программу в автозагрузку?» — начинающие пользователи находят ответ достаточно быстро, то вопрос о запуске скрипта, при выключении/перезагрузки, ставит их в тупик. В статье будет описан стандартный способ для автоматического выполнения команд при включении и выключении linux, а также более простой способ для пользователей, у которых установлен gdm и графический интерфейс, например ubuntu.

Консольный вариант.

Немного теории.
Следует знать, что в Linux существует 7 уровней запуска. Однако, использоваться могут только 6.
Как у всех уважающих себя программ отсчёт начинается с 0-ля.
0 — Остановка или выключение системы.
1 — Однопользовательский режим.
2 — Многопользовательский режим, но без поддержки сети.
3 — Тоже самое, но с сетью.
4 — Добавили для красоты Не используется.
5 — Графический режим с загрузкой X сервера.
6 — Перезагрузка.
Если перейти в папку /etc (В некоторых дистрибутивах /etc/rc.d) то можно увидеть папки с 7-мью уровнями запуска.

Например при выключении компьютера, выполнятся все скрипты из папки rc0.d



Тут следует остановится по подробнее. Дело в том, что самих скриптов (а точнее сценариев) в этой папке нету, а есть только ссылки на файлы, которые лежат в папке /etc/init.d. Эти сценарии выполняют различные задачи, в зависимости от параметра start или stop (например /etc/init.d/reboot start и /etc/init.d/reboot stop это разные команды, а /etc/init.d/reboot вообще не будет работать). Если в ссылке стоит первая буква S, то значит сценарию подаётся параметр start, а если стоит буква K(от слова kill), то параметр stop. Цифра после буквы обозначает порядок выполнения сценария.
Например, на выше вставленном скриншоте вначале выполниться команда /etc/init.d/hddtemp stop, а уже позже /etc/init.d/networking start.
Хватит теории. Переходим к практике.
Для того, чтобы добавить команду в автозагрузку, достаточно поместить её в файл /etc/rc.local.

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

sudo nano /etc/rc.local

И помещаем наши команды чуть выше строчки с exit 0.
Для того, что бы команды выполнялись перед выключением или перезагрузкой нам нужно создать сценарий в папке /etc/init.d

sudo nano /etc/init.d/имя_сценария

Вставляем следующий код:

#! /bin/sh
case "$1" in
start)
echo "подан сигнал start"
;;
stop)
echo "подан сигнал stop"
;; esac

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

...
case "$1" in
start)
#
;;
...

Теперь делаем файл исполняемым:

sudo chmod +x /etc/init.d/имя_сценария

sudo update-rc.d имя_сценария start 20 0 6 . stop 1 0 6 .

Точки важны (обе). Исследуя просторы интернета, у меня сложилось впечатление, что синтаксис этой программы иногда меняется. Актуальные примеры можно посмотреть по команде «man update-rc.d». Примеры будут в низу.

Эта команда создаст по 2 ссылки в каталогах /etc/rc0 .d (второе число в команде) и /etc/rc6 .d (третье число в команде). Причём вначале будет выполняться сценарий с параметром stop (т.к. стоит 1), а уже потом с параметром start (т.к. стоит 20).
Если второй параметр не нужен, то можно выполнить команду:

sudo update-rc.d имя_сценария stop 1 0 6 .

Советую ставить приоритет повыше (т.е. число после start или stop должно быть маленьким), желательно меньше 20. В обратном случае у меня иногда зависал компьютер при попытке перезагрузиться.

Для пользователей ubuntu, да и многих других современных дистрибутивов с gdm можно воспользоваться…

Графический вариант.

Что касается автозагрузки то можно воспользоваться способом описанным .
Или просто открыть «автоматически запускаемые приложения» командой:

gnome-session-properties

Для выполнения скрипта при выключении компьютера, помещаем его в файл /etc/gdm/PostSession/Default

sudo gedit /etc/gdm/PostSession/Default

Прямо над строчкой exit 0.